5.13.1 接待员
你的第一个公民:接待员
既然你已经掌握了Ethereum的基础知识,那么我们来谈谈你的第一份严肃的合同。Frontier是一个广阔开放的领域,有时你可能会感到孤独,所以我们的第一个生意是创造一个自动伴侣,当你感到孤独时迎接你。我们称他为“Greeter”。 Greeter是一个存活在blockchain上的智能数字实体,根据其输入,能够与任何与之交互的人进行对话。它或许不健谈,但它是一个很好的听众。这是它的代码:
contract mortal {
/* Define variable owner of the type address*/
address owner;
/* this function is executed at initialization and sets the owner of the contract */
function mortal() { owner = msg.sender; }
/* Function to recover the funds on the contract */
function kill() { if (msg.sender == owner) suicide(owner); }
}
contract greeter is mortal {
/* define variable greeting of the type string */
string greeting;
/* this runs when the contract is executed */
function greeter(string _greeting) public {
greeting = _greeting;
}
/* main function */
function greet() constant returns (string) {
return greeting;
}
}
你会注意到,这段代码中有两个不同的合约:“mortal”和“greeter”。这是因为Solidity(我们使用的高级合约语言)具有继承性,这意味着一个合同可以继承另一个合约的特征。这对于简化编码非常有用,因为每次不需要重写合同的常见特征,并且所有合约都可以写成更小,更可读的块。所以只要宣布greeter是mortal,你就继承了“mortal”合约的所有特征,并保持了这个简洁易懂的代码。
从“mortal”继承的特征仅仅意味着,在不再需要合约的情况下,greeter合约可以被其所有者杀死,清理blockchain并收回锁定的资金。在默认情况下,ethereum中的合约是永生的,没有所有者,这意味着一旦部署了,作者就不再有特权了。在部署前考虑一下。
安装编译器
在您能够部署之前,您将需要准备两件事:编译过的代码和应用程序二进制接口(Application Binary Interface),这是一种定义如何与合约进行交互的参考模板。 前者可以使用编译器获得。您应该在您的geth
控制台上内置一个solidity编译器。要测试它,请使用以下命令:
eth.getCompilers()
如果你安装它,它应该输出如下:
['Solidity' ]
如果命令返回错误,那么您需要安装它。
使用在线编译器
如果您没有安装solC,我们有一个在线的solidity编译器可供使用。但请注意,如果编译器受到威胁,则您的合同不安全。因此,如果您想使用在线编译器,我们鼓励您建立自己的在线编辑器。
在Ubuntu上安装SolC
按control+c退出控制台(或键入exit)并返回到命令行。打开终端并执行以下命令:
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
which solc
记下最后一行给出的路径,你很快就会用到。
在Mac上安装SolC
你需要brew,以在你的mac上安装SolC
brew install cpp-ethereum
brew linkapps cpp-ethereum
which solc
在Windows上安装SolC
你需要借助chocolatey来安装SolC
cinst -pre solC-stable
Windows比这更复杂,你需要等一下。
如果您安装了SolC Solidity Compiler,则需要通过删除空格来重新格式化,以使其适合字符串变量(有一些在线工具可以执行此操作)
从源文件编译
git clone https://github.com/ethereum/cpp-ethereum.git
mkdir cpp-ethereum/build
cd cpp-ethereum/build
cmake -DJSONRPC=OFF -DMINER=OFF -DETHKEY=OFF -DSERPENT=OFF -DGUI=OFF -DTESTS=OFF -DJSCONSOLE=OFF ..
make -j4
make install
which solc
将您的编译器链接到Geth
现在[返回到控制台]并输入此命令来安装solC,将path / to / solc
替换为您执行的最后一个命令的路径:
admin.setSolc("path/to/solc")
现在再次键入:
eth.getCompilers()
如果您现在已经安装了SolC,那么恭喜,您可以继续阅读。如果没有,那么请去我们的论坛或者subreddit,促使我们让此过程更容易。
编译合同
如果您安装了编译器,则现在需要通过删除换行符来重新格式化合同,以使其符合字符串变量(有一些在线工具可以执行此操作):
var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'
var greeterCompiled = web3.eth.compile.solidity(greeterSource)
你现在已经编译了你的代码。现在你需要准备部署,这包括设置一些变量,就像你的问候语。编辑下面的第一行,输入一些比“Hello World!”更有趣的话,并执行以下命令:
var _greeting = "Hello World!"
var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);
var greeter = greeterContract.new(_greeting,{from:web3.eth.accounts[0], data: greeterCompiled.greeter.code, gas: 1000000}, function(e, contract){
if(!e) {
if(!contract.address) {
console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
})
使用在线编译器
如果您没有安装solC,可以直接使用在线编译器。将上面的源代码复制到在线solidity编译器,然后你的编译代码应该出现在左窗格中。将标记为Geth deploy框中的代码复制到文本文件。现在把第一行改成你的问候语:
var _greeting = "Hello World!"
现在您可以将生成的文本粘贴到您的geth窗口。等待三十秒钟,您会看到如下消息:
Contract mined! address: 0xdaa24d02bad7e9d6a80106db164bad9399a0423e
您可能会被要求提供您在开始时选择的密码,因为您需要支付部署合约所需的gas费用。这份合约估计需要17.2万个gas用来部署(根据在线solidity编译器),在撰写本文时,测试网上的gas价格为1至10 microethers/每单位gas(昵称为“szabo”,换算成wei后是1后面加12个0)。要知道ether的最新价格,您可以在网络统计页面上看到最新的gas价格,并将这两个术语相乘。
请注意,成本并不支付给ethereum开发人员,而是付给矿工,他们提供维护网络运行的计算机。gas价格是由当前市场供求计算的。如果gas价格太高,你可以成为矿工,降低你的要价。 不到一分钟之后,你应该有一个合约地址的日志,这意味着你已经成功地部署了你的合约。您可以使用以下命令验证已部署的代码(已编译):
eth.getCode(greeter.address)
如果它返回除“0x”之外的任何东西,那么恭喜!你的小Greeter是活的!如果合约再次创建(通过执行另一个eth.sendTransaction),它将被发布到一个新的地址。
运行Greeter
为了调用您的机器人,只需在您的终端中键入以下命令:
greeter.greet();
由于此调用在blockchain上不改变任何东西,因此立即返回,无需任何gas成本。你应该看到它返回你的问候语:
'Hello World!'
让其他人与您的代码进行交互
为了让其他人运行你的合约,他们需要两件东西:合约所在的地址和ABI(应用二进制接口),这是一种用户手册,描述其功能的名称以及如何调用它们。为了获取他们,运行以下命令:
greeterCompiled.greeter.info.abiDefinition;
greeter.address;
然后,您可以实例化一个可以用于在连接到网络的任何计算机上调用合约的JavaScript对象。替换'ABI'和'地址'以在javascript中创建一个合约对象:
var greeter = eth.contract(ABI).at(Address);
var greeter = eth.contract(ABI).at(Address);
任何人都可以通过简单的调用来实例化这个特定的例子:
var greeter2 = eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'function'},{constant:true,inputs:[],name:'greet',outputs:[{name:'',type:'string'}],type:'function'},{inputs:[{name:'_greeting',type:'string'}],type:'constructor'}]).at('greeterAddress');
将greeterAddress
替换为您的合同地址。
提示:如果您的计算机中没有正确安装solidity编译器,则可以从在线编译器获取ABI。为此,请使用下面的代码,仔细地使用编译器中的abi替换greeterCompiled.greeter.info.abiDefinition。
自己清理后:
你的第一份合约生效时,你肯定很兴奋,但这个兴奋有时会慢慢消失,当所有者继续写下进一步的合约时,导致在blockchain上被放弃的合约很不开心。未来,可能会实施blockchain租金,以增加blockchain的可扩展性,但现在,成为一个好的公民,人性化地放弃了你的遗弃的机器人。
与上一次不同,我们不会调用,因为我们希望改变blockchain上的东西。这要求将交易发送到网络,并为所做的更改支付费用。自杀由网络补贴,因此比一般的交易费用要少得多。
greeter.kill.sendTransaction({from:eth.accounts[0]})
您可以根据看到是否返回0来验证合约是否完成:
eth.getCode(greeter.contractAddress)
请注意,每个合同都必须执行自己的kill条款。在这种特殊情况下,只有创建合同的帐户才能将其杀死。
如果你不添加任何杀死条款,它可能永远存在(或者至少直到frontier合约都被擦除),独立于你和任何实际边界,所以在你将其放置网络之前,请检查关于它的本地法律条款,包括对技术出口的任何可能的限制,对言论的限制,也可能是有声数字的民事权利立法。请人性化地对待你的机器人。