이 기사는 PHP와 Ethereum 클라이언트 간의 상호 작용에 대한 관련 지식 포인트를 알려주며 도움이 필요한 친구들이 따라하고 배울 수 있습니다.
php는 이더리움 rpc 서버와 통신합니다
1. Json RPC
Json RPC는 json 기반의 원격 프로시저 호출입니다. 간단히 말하면 json 형식으로 데이터를 게시하고 rpc 서버에서 메서드를 호출하는 것입니다. 이 json 형식은 일반적으로 다음 항목이 있습니다.
{ "method": "", "params": [], "id": idNumber }
method: method name
params: 매개변수 목록
id: 프로시저 호출에 대한 고유 식별 번호
2. Json RPC 클라이언트 빌드
<?php class jsonRPCClient { /** * Debug state * * @var boolean */ private $debug; /** * The server URL * * @var string */ private $url; /** * The request id * * @var integer */ private $id; /** * If true, notifications are performed instead of requests * * @var boolean */ private $notification = false; /** * Takes the connection parameters * * @param string $url * @param boolean $debug */ public function __construct($url,$debug = false) { // server URL $this->url = $url; // proxy empty($proxy) ? $this->proxy = '' : $this->proxy = $proxy; // debug state empty($debug) ? $this->debug = false : $this->debug = true; // message id $this->id = 1; } /** * Sets the notification state of the object. In this state, notifications are performed, instead of requests. * * @param boolean $notification */ public function setRPCNotification($notification) { empty($notification) ? $this->notification = false : $this->notification = true; } /** * Performs a jsonRCP request and gets the results as an array * * @param string $method * @param array $params * @return array */ public function __call($method,$params) { // check if (!is_scalar($method)) { throw new Exception('Method name has no scalar value'); } // check if (is_array($params)) { // no keys $params = $params[0]; } else { throw new Exception('Params must be given as array'); } // sets notification or request task if ($this->notification) { $currentId = NULL; } else { $currentId = $this->id; } // prepares the request $request = array( 'method' => $method, 'params' => $params, 'id' => $currentId ); $request = json_encode($request); $this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n"; // performs the HTTP POST $opts = array ('http' => array ( 'method' => 'POST', 'header' => 'Content-type: application/json', 'content' => $request )); $context = stream_context_create($opts); if ($fp = fopen($this->url, 'r', false, $context)) { $response = ''; while($row = fgets($fp)) { $response.= trim($row)."\n"; } $this->debug && $this->debug.='***** Server response *****'."\n".$response.'***** End of server response *****'."\n"; $response = json_decode($response,true); } else { throw new Exception('Unable to connect to '.$this->url); } // debug output if ($this->debug) { echo nl2br($debug); } // final checks and return if (!$this->notification) { // check if ($response['id'] != $currentId) { throw new Exception('Incorrect response id (request id: '.$currentId.', response id: '.$response['id'].')'); } if (!is_null($response['error'])) { throw new Exception('Request error: '. var_export($response['error'], true)); } return $response['result']; } else { return true; } } } ?>
비교적 간단한 코드, 게으른 경우 , take 과거에는 그냥 사용하세요. packagist.org에 가서 직접 rpc 클라이언트를 찾을 수도 있습니다.
3. RPC를 호출하는 두 가지 유형의 메소드
호출해야 하는 두 가지 유형의 메소드가 있습니다. 하나는 RPC 서버 고유의 메소드입니다. , 다른 하나는 계약 방법입니다.
RPC 서버 메서드는 json 형식을 호출합니다.
{ "method": "eth_accounts", "params": [], "id": 1 }
RPC 서버에 내장된 메서드 목록
내장 메서드를 호출하는 방법은 비교적 간단합니다. 위 링크를 참조하세요. 대부분은 예시입니다.
계약 메서드는 json 형식을 호출합니다
계약 메서드를 호출하려면 내장 메서드에서 eth_call을 사용해야 합니다. 계약 메서드 이름과 계약 메서드 매개 변수 목록은 params를 사용하여 반영됩니다. 계약에서 BalanceOf 메소드를 호출하려면 json 데이터를 어떻게 구성해야 합니까?
우선 getBalanace의 함수 구현을 살펴보세요:
function balanceOf(address _owner) public view returns (uint256 balance)
함수 프로토타입 추출:
balanceOf(address)
geth 콘솔에서 명령을 실행하세요.
web3.sha3("balanceOf(address)").substring(0, 10)
Get the function hash "0x70a08231"
Assumption 쿼리할 주소는 address _owner = "0x38aabef4cd283ccd5091298dedc88d27입니다. c5ec5750", 앞에 있는 "0x"를 제거하세요. 왼쪽에 24개의 0을 추가하여(일반 주소 길이는 42비트이며 '0x'를 제거한 후 40비트임) 64비트 16진수 맞춤형 매개변수를 형성합니다.
최종 매개변수는 "0x70a082310000000000000000000000038aabef4cd283ccd5091298dedc88d입니다. 27c5ec5750"
가정하자 우리 계약 주소는 "0xaeab4084194B2a425096 fb583Fbcd67385210ac3"입니다.
그런 다음 최종 json 데이터는 다음과 같습니다.
{ "method": "eth_call", "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0x70a0823100000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750"}, "latest"], "id": 1 }
위 json 데이터를 포스트 모드로 보냅니다. 서버에 계약 메서드 "balanceOf"를 호출하여 토큰을 쿼리할 수 있습니다.
계약의 다른 메소드를 호출하는 경우에도 위의 메소드를 따라야 합니다. 이체 메소드를 다시 분석하여 감상을 심화해 보겠습니다.
먼저 코드의 함수 구현을 살펴보세요.
function transfer(address _to, uint256 _value) public returns (bool)
Second로 기능 프로토 타입을 추출합니다. "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "0x"로 이동하여 64비트에 0을 추가합니다.
두 번째 매개변수는 uint256_value = 43776을 가정하고 16진수 시스템이 됩니다. "0xab00" 이후 "0x"로 이동하여 64에 0을 추가합니다. 함께 연결하세요"0xa9059cbb000000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000 000000000000000000 0000000000000000000000000ab00"json 데이터 빌드:transfer(address,uint256) //注意逗号后面不能有空格
이체자 주소
to 계약 주소
data 위에서 얻은 숫자 Operation
위 단계를 코드로 변환합니다.
web3.sha3("transfer(address,uint256)").substring(0, 10)
코드는 비교적 간단합니다. 주의해야 할 몇 가지 사항이 있습니다. 포인트:
전달 함수는 10^-18로 매우 작으므로 1000번을 전달하려면 실제로 10의 18승을 곱해야 합니다. 여기서 18은 소수입니다.
포인트 1로 인해, pow 함수 대신 bcpow를 사용해야 합니다.
PHP와 함께 제공되는 decex 함수는 사용할 수 없습니다. dechex에서는 정수 유형이 PHP_INT_MAX보다 클 수 없으며 이 숫자는 32비트 시스템에서 4294967295입니다. 1번 항목으로 인해 모든 숫자는 10의 18승을 곱해야 하므로 결과값은 PHP_INT_MAX보다 훨씬 큽니다. 구현 방법을 모르는 경우에는 10진수를 16진수로 직접 변환하는 것이 좋습니다. 위의 코드에.
이체 등 특정 계약 방법을 실행할 때는 먼저 사용자 잠금을 해제해야 합니다.
트랜잭션을 보낸 후 서버 측에서 마이닝을 시작해야 트랜잭션이 실제로 블록에 기록됩니다. , 예를 들어 이체를 호출한 후 상대방이 계정을 받지 못한 것을 발견하면 아직 놀라지 말고 채굴을 시작하십시오. 자동 코드 마이닝을 활성화하려면 geth --rpc 끝에 --mine을 추가하세요... 테스트:
{ "method": "eth_call", "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0xa9059cbb00000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000000000000000000000000000000000000000000000000000ab00"}, "latest"], "id": 1 }
위 내용은 PHP와 Ethereum 클라이언트 간의 상호 작용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!