以太坊学习之开发编译部署调用智能合约

本文根据汪晓明的视频资料整理,ubuntu16.04测试正确。 

1.打开geth控制台

~$ geth --datadir ~/pengfan/eth --dev

在另一个终端输入

~$ geth --dev console 2>>file_to_log_output

2.查看、设置编译器

> eth.getCompilers()
[]

设置solc为编译器

> admin.setSolc("/usr/local/bin/solc")
Error: exit status 1
    at web3.js:3119:20
    at web3.js:6023:15
    at web3.js:4995:36
    at <anonymous>:1:1

提示错误,更改路径成“/usr/bin/solc”

~$ whereis solc
solc: /usr/bin/solc /usr/local/bin/solc
> admin.setSolc("/usr/bin/solc")
"solc, the solidity compiler commandline interface\nVersion: 0.4.7+commit.822622cf.Linux.g++\n"

再次查看

>eth.getCompilers()
["Solidity"]
  • 1
  • 2

3.编写智能合约

>source="contract test { function multiply(uint a) returns(uint d) { return a * 7; }}"
  • 1

4.编译智能合约

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

以太坊学习之开发编译部署调用智能合约

code——编译后的EVM字节码 
info——编译器返回的原数据 
abiDefinition——应用程序二进制接口定义 
compilerOptions——编译参数

5.准备工作:创建账户并激活

在以太坊上创建智能合约就是使用一个外部账户(EOA)向区块链中发送一个交易。

> personal.newAccount("123456")
"0x733bf98c0e218b430db0fe1d4c9ef04341444a82"
> personal.listAccounts
["0x733bf98c0e218b430db0fe1d4c9ef04341444a82"]
> eth.getBalance(personal.listAccounts[0])
0
> miner.start()
true
> eth.blockNumber
2
> eth.getBalance(personal.listAccounts[0])
15000000000000000000
> address=eth.accounts[0]
"0x733bf98c0e218b430db0fe1d4c9ef04341444a82"
> personal.unlockAccount(address,"123456",10000)
true

以太坊学习之开发编译部署调用智能合约 
6.指定创建合约的账户

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

7.部署合约

部署合约就是将编译好的合约字节码以外部账号发送交易到一个空地址的形式部署到以太坊区块链上


> abi=contract.info.abiDefinition

以太坊学习之开发编译部署调用智能合约 
8.

web3.eth.contract可以创建一个合约对象,这个对象可以在指定地址上初始化一个合约:

> MyContract=eth.contract(abi)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  eth: {
    accounts: ["0x733bf98c0e218b430db0fe1d4c9ef04341444a82"],
    blockNumber: 14,
    coinbase: "0x733bf98c0e218b430db0fe1d4c9ef04341444a82",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 41253,
    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),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    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()
}

9.将合约部署到区块链上

>myContract=MyContract.new({from:address,data:contract.code})
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  address: undefined,
  transactionHash: "0xc99efdc9ffb6f8283556b5de80c76f9bb3b37faf62bb8374ddf79480257866ac"
}

10.检查交易池,有一个待处理事项,要通过挖矿让交易生效,红色框中说明交易已经发送到区块链中了,等待矿工确认。

> txpool.status
{
  pending: 1,
  queued: 0
}
  • 以太坊学习之开发编译部署调用智能合约
> txpool.status
{
  pending: 0,
  queued: 0
}
> miner.stop()
true

11.合约写进区块链之后就可以调用了(合约交互),以下为合约调用代码,通过abi取合约对象

使用eth.contract来定义一个合约类,定义的合约类遵从ABI定义

> Multiply7=eth.contract(contract.info.abiDefinition)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      type: "function"
  }],
  eth: {
    accounts: ["0x733bf98c0e218b430db0fe1d4c9ef04341444a82"],
    blockNumber: 24,
    coinbase: "0x733bf98c0e218b430db0fe1d4c9ef04341444a82",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 0,
    mining: false,
    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),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    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()
}

12.指定特定地址,得到该地址上的合约实例

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

在实例中能够调用的函数有两个:allEvents和multiply。multiply显然是一开始我们定义合约的时候写的函数。我们可以使用两种方法来调用multiply函数:sendTransaction(3, {from: address})和call(3)。

> myMultiply7.multiply.sendTransaction(3, {from:address})
"0x71eed110365e80fb4d9436c30f5480fb5522afa629f629be816d4b07ef8d7c83"
> myMultiply7.multiply.call(3)
21
> myMultiply7.multiply.call(8)
56

使用sendTransaction(3, {from: address})返回的值为一个字符串,这个字符串代表的是发送的交易的hash值。使用这个方法调用合约将会使调用的结果成为全局共识的一部分 
使用call(3)这个方法调用合约只会在本地上运行

要改变合约状态,只能用第一种方法。

转自:https://blog.csdn.net/p03721/article/details/54176353

如果你希望高效的学习以太坊DApp开发,可以访问汇智网提供的最热门在线互动教程:

其他更多内容也可以访问这个以太坊博客


上一篇:【技术帖】IE6所有标签元素支持hover伪类的解决方案


下一篇:通过iframe引入另外一个项目中的html片段到项目中,解决样式,高度,兼容等问题的策略