Hello World——一个关于智能合约的信仰

前言

任何程序员学习一个新的编程语言,一个最重要的仪式就是写出一个能输出Hello World!的程序。完成后,这才算打开一个新世界的大门。本文主要介绍如何使用智能合约输出一个Hello World!。本文的步骤说明十分简单(但步骤完整),大家如果想要看详细的步骤说明,请参考智能合约编写实例这篇文章,里面的实例描述更加详细。

打开测试网络的控制台

输入以下命令:

geth --datadir "~/ethdev" --dev console 2>> geth.log

这样我们就打开了测试网的控制台,之后的步骤如无特别说明都将在控制台中完成。

编写智能合约

> source = "contract test { function hello() returns(string s){return 'hello world!';}}"
"contract test { function hello() returns(string s){return 'hello world!';}}"

编译智能合约

> contract = eth.compile.solidity(source).test

指定创建合约的外部账户

我们首先需要从当前的账户里选择一个作为创建智能合约的外部账户:

> address = eth.accounts[0]
"0x62b1746767522b36f6421e630fa0198151d72964"

然后将该账户激活:

> personal.unlockAccount(address,'123456',10000)
true

最后开启挖矿,为处理交易做准备:

> miner.start()
true

部署合约

部署合约就是将编译好的合约字节码通过外部账号发送交易的形式部署到以太坊区块链上。输入以下命令:

> abi = [{constant:false,inputs:null}]
[{
    constant: false,
    inputs: null
}]
> MyContract = eth.contract(abi)
{
  abi: [{
      constant: false,
      inputs: null
  }],
  eth: {
    accounts: ["0x62b1746767522b36f6421e630fa0198151d72964", "0xaa79b5468a4f4cf35a32cc976f689a5db5873f0c"],
    blockNumber: 600,
    coinbase: "0x62b1746767522b36f6421e630fa0198151d72964",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: "0x62b1746767522b36f6421e630fa0198151d72964",
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 3302,
    mining: true,
    pendingTransactions: [],
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(fil, callback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getNatSpec: function(),
    getPendingTransactions: function(callback),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}
> myContract = MyContract.new({from:address,data:contract.code})
{
  abi: [{
      constant: false,
      inputs: null
  }],
  address: undefined,
  transactionHash: "0x9f0f739a5827796fc1466a09e7771eef0978262a007f8c75c789cdcf1d9c3d4b"
}

这时,我们可以检查一下交易池,查看当前交易的待处理状况:

> txpool.status
{ pending: 1, queued: 0 }

耐心等待一段时间,等待矿工确认完成后,我们再次使用txpool.status命令查看交易池的状态:

> txpool.status
{ pending: 0, queued: 0 }

这就说明该条交易已经成功被处理了。

与合约交互

首先我们需要使用eth.contract来定义一个合约类,定义的合约类遵从ABI定义1

> Hello = eth.contract(contract.info.abiDefinition)
{
  abi: [{
      constant: false,
      inputs: [],
      name: "hello",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  eth: {
    accounts: ["0x62b1746767522b36f6421e630fa0198151d72964", "0xaa79b5468a4f4cf35a32cc976f689a5db5873f0c"],
    blockNumber: 623,
    coinbase: "0x62b1746767522b36f6421e630fa0198151d72964",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: "0x62b1746767522b36f6421e630fa0198151d72964",
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 3158,
    mining: true,
    pendingTransactions: [],
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(fil, callback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getNatSpec: function(),
    getPendingTransactions: function(callback),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}

然后得到合约实例:

> hello = Hello.at(myContract.address)
{
  abi: [{
      constant: false,
      inputs: [],
      name: "hello",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  address: "0x67392c276e261d916243b7ba200d2c005d35ae57",
  transactionHash: null,
  allEvents: function(),
  hello: function()
}

使用call()调用:

> hello.hello.call()
"hello world!"

仪式完成!

阅读更多

更多精彩内容