web3类的介绍 | PHP实现ETH 1

下面是使用web3.php获取节点版本信息的代码:rpc-web3.php


require('../vendor/autoload.php');

use Web3\Web3;
use EthTool\Callback;

$web3 = new Web3('http://localhost:8545');
$web3->clientVersion(function($err,$result){
  if($err) throw $err;
  echo $result . PHP_EOL;
});

$cb = new Callback;

$web3->clientVersion($cb);
echo $cb->result . PHP_EOL;

$web3->sha3('hello,ethereum',$cb);
echo $cb->result . PHP_EOL;

$web3->eth->gasPrice($cb);
echo $cb->result . PHP_EOL;

$web3->eth->accounts($cb);
$accounts = $cb->result;
print_r($accounts);

$web3->eth->getBalance($accounts[0],$cb);
echo $cb->result . PHP_EOL;
'1604889808'>

理解web3.php的命名规则

web3.php的命名空间为Web3,所有的类都定义在该空间内。其中, Web3\Web3是包的入口类,只需指定节点URL就可以进行实例化了。

方法调用的结果是通过回调函数传入的,其第一个参数表示错误对象, 如果非空就意味着执行过程出现了错误,你可以调用其getMessage()方法 获得错误的描述信息,或者像我一样不负责任的抛出异常。第二个参数则表示 JSON RPC响应包中的result字段的内容 —— 注意不是整个响应包。

如果你不喜欢写大量的嵌套回调,或者使用引用来从回调域中返回结果,那么 可以写一个简单的callable类:


namespace EthTool;

class Callback{
  function __invoke($error,$result){
    if($error) throw $error;
    $this->result = $result;
  }
}

?>

然后直接把一个Callback实例对象丢给web3.php的函数做回调:

$cb = new Callback;
$eth->accounts($cb);
print_r($cb->result);

在函数的命名上,web3.php尽量贴近对应的rpc接口名称,例如与web3_clientVersion 对应的,就是Web3类的clientVersion()方法,与web3_sha3对应的就是 Web3类的sha3()方法 —— 横线之前的做类名,横线之后的做方法名:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RtcKG4F3-1650265927260)(https://www.li6.cc/assets/img/loading2.gif)]

在web3.php中没有实现db_*相关的接口,如果需要的话你可以自己补上。但是 它在Web3Personal类中实现了geth的管理接口,这个非标扩展接口主要用于 节点账户的管理,例如创建新账户、解锁账户等等,一些非常实用的功能。

Web3入口类

Web3\Web3是一个入口类,通过它即可访问其他类的实例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-auwsUKTZ-1650265927262)(https://www.li6.cc/assets/img/loading2.gif)]

例如,上面的代码 (demo:repo\chapter2\rpc-web3.php)

eth->accounts($cb); 
$accounts = $cb->result;
$web3->eth->getBalance($accounts[0],$cb);
echo 'balance: ' . $cb->result . PHP_EOL;

利用入口类实例的eth对象调用eth->accounts接口获取节点账户列表,然后调用eth->getBalance接口获取第一个账户的余额,Web3\Provider封装了Http请求的细节,而Web3\Utils则封装了一些有用的工具方法,我们在后面会用到。

账户管理

在这一部分,我们将学习如何使用php管理以太坊账户,这包括:

了解私钥、公钥和账户的关系 离线创建以太坊账户 导入其他账户私钥 创建和使用钱包 创建和使用账户凭证

以太坊作为一个去中心化的系统,必然不会采用中心化的账户管理 方案 —— 没有一个中心数据库来保存以太坊平台上的所有账户信息。 事实上,以太坊使用非对称密钥技术来进行身份识别,一个以太坊 账户对应着一对密钥:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qs7C7uIE-1650265927262)(https://www.li6.cc/assets/img/loading2.gif)]

我们将使用simplto/elliptic-php和kornrunner/keccak这两个包来创建离线账户,并参考nebulasio的代码实现keystore钱包。 以太坊使用非对称密钥对来进行身份识别,每一个账户都有 对应的私钥和公钥 —— 私钥用来签名、公钥则用来验证签名 —— 从而 在非可信的去中心化环境中实现身份验证。

事实上,在以太坊上账户仅仅是对应于特定非对称密钥对中公钥的20字节 哈希:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o82NapPZ-1650265927262)(https://www.li6.cc/assets/img/loading2.gif)]

从私钥可以得到公钥,然后进一步得到账户地址,而反之则无效。 显然,以太坊不需要一个中心化的账户管理系统,我们可以根据以太坊约定 的算法自由地生成账户。

在php中,可以使用simplto/elliptic-php包的EllipticEC类来创建 密钥对,然后使用kornrunner/keccak包计算账户地址:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3x4ipqnx-1650265927263)(https://www.li6.cc/assets/img/loading2.gif)]

例如,demo: repo\chapter3\ ew-account.php

创建私钥生成账户和公钥

首先创建一个私钥对,然后再利用公钥生成账户地址:

genKeyPair();

$privateKey = $keyPair->getPrivate()->toString(16,2);
$publicKey = $keyPair->getPublic()->encode('hex');
$address = '0x' . substr(Keccak::hash(substr(hex2bin($publicKey),1),256),24);

echo 'Private Key' . PHP_EOL;
echo $privateKey . PHP_EOL;
echo 'Public Key' . PHP_EOL;
echo $publicKey . PHP_EOL;
echo 'address' .PHP_EOL;
echo  $address . PHP_EOL;

?>

我们已经知道,只有私钥是最关键的,公钥和账户都可以从私钥一步步 推导出来。

假如你之前已经通过其他方式有了一个账户,例如使用Metamask创建 的钱包,那么可以把该账户导入php应用,重新生成公钥和账户地址: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUhe1MNG-1650265927263)(https://www.li6.cc/assets/img/loading2.gif)]

利用私钥还原账户和公钥

我们使用EllipticEC类的静态方法keyFromPrivate()来导入 私钥。例如: demo:repo\chapter3\import-key.php

keyFromPrivate('0x133be114715e5fe528a1b8adf36792160601a2d63ab59d1fd454275b31328791');

$privateKey = $keyPair->getPrivate()->toString(16,2);
$pubKey = $keyPair->getPublic()->encode('hex');
$address = '0x' . substr(\\kornrunner\\Keccak::hash(substr(hex2bin($pubKey), 1), 256), 24);

echo 'Private Key' . PHP_EOL;
echo $privateKey . PHP_EOL;
echo 'Public Key' . PHP_EOL;
echo $pubKey . PHP_EOL;
echo 'address' .PHP_EOL;
echo  $address . PHP_EOL;
?>

你可能感兴趣的:(区块链,我和php的故事,php,以太坊,开发语言)