说明
最近在做以太坊智能合约DAPP的开发,在使用PHP做接口的时候遇到很多问题,记录下来当做参考。本文的操作环境为Mac,已经安装好truffle
/ganache
等开发需要的相关工具
编写智能合约
-
新建truffle项目
mkdir test_truffle cd test_truffle truffle init
- 新建一个Hello_falco合约并编译
进入contracts目录,新建Hello_falco.sol
pragma solidity ^0.4.17;
contract Hello_falco {
function say() public pure returns (string) {
return "Hello falco";
}
function print(string name) public pure returns (string) {
return name;
}
}
可以看到Hello_falco.sol这个合约已经编译了
编译好的合约都会在build/contracts下生成一个json文件,打开刚刚生成的Hello_falco.json文件,可以看到有abi
,bytecode
等信息,以后要用到
部署合约到ganache
配置truffle.js
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 9545,//我本机的ganache端口
network_id: "*"
}
}
};
合约已经迁移过去了,会消耗主账号一部分ETH,可以看到账号余额已经发生了变化
测试合约
执行truffle console
,打开控制台
truffle(development)> var contract;
undefined
truffle(development)> Hello_falco.deployed().then(function(instance){contract= instance;});
undefined
truffle(development)> contract.say();
'Hello falco'
使用PHP+Laravel的方式部署合约
上面为使用truffle部署和测试合约,下面会使用PHP操作web3的方式再部署一次
安装composer包
composer require jcsofts/laravel-ethereum
详细安装说明Laravel ethereum
配置.env
文件
ETH_HOST=http://127.0.0.1
ETH_PORT=9545
编写PHP部署合约方法
use Jcsofts\LaravelEthereum\Facade\Ethereum;
use Jcsofts\LaravelEthereum\Lib\EthereumTransaction;
private $mainAddress = "0x80d2F5BA14983a671e29068958Eb60a45b01e49c";
public function deploy(){
$byteCode = "xxx";
$ethereumTransaction = new EthereumTransaction(
$this->mainAddress,null,null,'0x47b760',null,$byteCode);
$response = Ethereum::eth_sendTransaction($ethereumTransaction);
dd($response);
}
主账号地址为ganache的第一个账户地址
智能合约的byteCode使用的是编译好的Hello_falco.json中的bytecode段0x47b760
为gas,我设置的固定值用作测试
执行deploy方法之后,我们把response打印出来
0x0ca011fd3856b34ee5169ec0c0ddad465f5e6bec1795751b41bbab9e295ac0a0
这是一段TransactionHash,稍等之后我们来通过它来取部署后的合约地址
public function receipt(){
$hash = "0x0ca011fd3856b34ee5169ec0c0ddad465f5e6bec1795751b41bbab9e295ac0a0";
$response = Ethereum::eth_getTransactionReceipt($hash);
dd($response);
}
如图我们拿到了合约地址,之后就可以通过上面的合约地址来执行智能合约内定义的方法体了
PHP调用智能合约内的say方法
要访问合约内的方法我们首先要获取方法的签名(function signature),那么如何获取方法签名呢?
1.进入truffle console
控制台
2.通过web3的sha3方法计算
truffle(development)> web3.sha3("say()")
'0x954ab4b21481711a1e363afa5d2b9003ed2702949b83f2d36d03d3b90ebb0f26'
truffle(development)> web3.sha3("say()").substr(2,8)
'954ab4b2'
只需要拿到除去0x的前八位即可
继续编写say方法php函数
public function say(){
$contractAddress = "0x00a800ff57861294dd3db449dbe0367ae66d9e86";
$ethereumTransaction = new EthereumTransaction(
$this->mainAddress,$contractAddress,null,'0x47b760',null,'0x954ab4b2');
$response = Ethereum::eth_sendTransaction($ethereumTransaction);
dd($response);
}
执行完之后我们会得到一串TransactionHash
如果一切正常那么我们的ganache log里会出现一个新区块,php返回的TransactionHash就是这个区块的Hash
如果出现错误或者方法不存在,会出现下面的情况
总结
以上是一个简单的hello world抛砖引玉,我们可以编写更复杂的合约,比如拍卖、竞猜的智能合约。
简单说下拍卖智能合约思路:
- 用户注册(新用户自动注册一个账户地址personal_importRawKey)
- 发起拍卖(最高者存在智能合约里)
- 拍卖结束获取合约中的最高者
- 关闭合约