我们写好一个合约后,一个合约如何部署到以太坊网络,并实现合约函数的调用呢?合约部署到以太坊网络上,也是一个类似交易的过程。首先向全网发送一个合约创建的交易,待矿工打包交易,并获得全网的认可从而生效后,则得到合约的地址;既而向这个地址发送消息调用,实现调用合约的某个函数。
初始创建合约
以太坊提供了基于JSON格式的JSON RPC API
1,可以通过套接字,HTTP等,用来与以太坊网络进行交互。
以太坊还提供了一套在上述基础上的,JavaScript语言封装的工具库web3.js
2。
如何使用web3.js创建合约建议参考此文,非常详尽:http://web3.tryblockchain.org/web3-js-in-action.html
不是所有的客户端都实现了对JSON RPC API
的全部支持。go客户端JSON RPC
的几乎全部支持,具体可以参见这里:https://github.com/ethereum/wiki/wiki/JSON-RPC。
合约中创建合约
在Solidity中创建一个合约非常简单,但创建者必须知道要创建的合约源码。通过下面的例子,我们来看下如何在合约中创建合约。
下面是一个要被创建的合约的源码:
pragma solidity ^0.4.0;
contract Test{
function add(uint a, uint b) constant returns (uint){
return a + b;
}
}
在创建者合约中,使用new
关键字创建合约,由于创建者合约必须要知道源码。我们可以把多个合约写到同一个文件,或使用import
关键字来引入关联合约,下面是引入Test
合约,并创建的一个实例的具体实现:
pragma solidity ^0.4.0;
import "./Test.sol";
contract NewContract{
function createAndCallContract() returns(address addr, uint result){
Test t = new Test();
return (t, t.add(1, 2));
}
}
上述实现中,我们首先引入了Test.sol
源代码文件。需要注意的是,使用./
说明两个文件是放在同级目录下,不以.
开头默认是以绝对路径寻址3。在合约NewContract
中,我们使用new
关键字部署了一个Test.sol
合约。成功调用后,我们不止可以得到合约部署的地址,也可以直接调用合约提供的函数。
构造器
每个合约都允许存在构造器,构造器是与合约同名的一个特殊函数,有且只能有一个,不允许重载。构造器将在合约创建时,执行一次,用于初始化一些配置。
pragma solidity ^0.4.0;
contract ContractConstructor{
uint public counter;
function ContractConstructor(){
counter++;
}
}
上述合约在创建成功后,counter
的值将为1
。说明合约在创建时,被调用了一次。
构造器内,由于合约尚未初始化完成,故不能使用this
来以external
的方式来调用当前合约中的函数,下面来看一个例子。
pragma solidity ^0.4.0;
contract A{
function A(){
innerCall();
//Exception during execution. (out of gas).
//this.externalCall();
}
function innerCall() internal {}
function externalCall() external{}
}
contract ConstructorCall{
function create(){
A a = new A();
}
}
上述的代码中,如果取消掉this.externalCall()
的注释,将导致创建时报错Exception during execution. (out of gas)
。因为合约尚未创建完成,不能通过外部方式调用。但我们可以使用internal
的方式使用函数,正如innerCall();
所示。
构造器还允许接收ether,只需要在构造器函数上增加payable
关键字,下面是一个简单的例子:
pragma solidity ^0.4.0;
contract ConstructorEther{
function ConstructorEther() payable {}
function getBalance() constant returns (uint){
return this.balance;
}
}
在上面的例子中,ConstructorEther
可以在创建时接收指定数量的ether。
关于作者
专注基于以太坊(Ethereum)的相关区块链(Blockchain)技术,了解以太坊,Solidity,Truffle,web3.js。
个人博客: http://tryblockchain.org
版权所有,转载注明出处
参考资料
基于JavaScript的封装。https://github.com/ethereum/wiki/wiki/JavaScript-API
处于某些特定的环境下,可以看到评论框,欢迎留言交流^_^。