以太坊部署简单智能合约记录*

solidity在线编译地址

以太坊solidity在线编译地址

开始步骤

geth的搭建环境和构建私有连比较简单,csdn博客很多,自行看下就好了啦

1、启动两个console

第一个启动以太坊的console控制台,启动参数可参考如下 
mygeth.exe --identity "newEth" --rpc --rpccorsdomain "*" --datadir "%cd%\chain" --port 30303 --rpcapi "db,eth,net,web3" --networkid 9999 console
大概是这样的 
启动第一个console 
第二个 新开一个终端连接以太坊的console,参考命令 
geth attach http://127.0.0.1:8545,通过geth attach来连接,后面就是ip和端口,默认端口是8545,可通过第一个启动进行自定义。 
连接上之后大概是这样的 
第二个console通过geth attach 连接

部署之前的准备

必须有一个账户,并且账户里面要有etc 
web3.js的API 
创建账户命令 
personal.newAccount('aaa111')单引号里面的是密码 
查看账户命令 
personal.listAccounts 
查看默认挖矿的账号命令 
web3.eth.coinbase 
启动挖矿的命令 
miner.start(1) 
总的来说 就是部署合约的前提条件是你必须要有一个账户,并且账户里面要有钱(多点好),然后再部署合约的时候需要解锁账户,只有解锁了账户才能把合约部署上去

开发准备

下面这段代码是个很简单的智能合约代码

pragma solidity ^0.4.4;
contract test { 
    function multiply(uint a) returns(uint d){
        return a * 6;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
编译合约

把上述代码拷贝到solidity在线编译器上面进行编译,如下图 
编译图 
把代码拷贝到中间,然后点击Start to compile按钮,右边会出现警告,忽略没有关系,我们测试的很简单,编译完成之后,点开旁边的Details。大概的图是这样的,这里只截取了一小部分,具体的点开看一下里面的注释就知道了.. 
编译的结果图

开始部署合约

我们找到Detail中的WEB3DEPLOY段落,这个就说怎么用web3进行部署,下面有两个命令,我们一次执行下

var testContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]);
var test = testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006006820290509190505600a165627a7a72305820bfce4073e896a63a9888320f0d5d07c04954fdb3c0420f79e3170786b086c9ff0029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

执行效果

> var testContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]);
undefined
> var test = testContract.new(
...    {
......      from: web3.eth.accounts[0],
......      data: '0x6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006006820290509190505600a165627a7a72305820bfce4073e896a63a9888320f0d5d07c04954fdb3c0420f79e3170786b086c9ff0029',
......      gas: '4700000'
......    }, function (e, contract){
......     console.log(e, contract);
......     if (typeof contract.address !== 'undefined') {
.........          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
.........     }
......  })
Error: authentication needed: password or unlock undefined
undefined
>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我们看到执行第二条命令的时候报错了,Error: authentication needed: password or unlock undefinedu,这是因为账户没有解锁,那我们就解锁下

> personal.unlockAccount(eth.accounts[0],"aaa111",1000000)
true
>
  • 1
  • 2
  • 3

返回true解锁成功,然后再执行上面命令中的第二条命令,这个时候就没有报错了,,

执行命令之后会出现这样的一段文字(出现这段文字的前提是你的第一个终端是在挖矿状态),address就是合约地址
Contract mined! address: 0xd26db0df7644ed6b1e46839273591bcd67cbcefd 
transactionHash: 0xde6570c862fff92f282fddf84901a0e376a3f972e7be8831eccbe2b2220a8e4a
  • 1
  • 2
  • 3
调用合约

在第二个终端执行,引号里面的值就是合约的地址,这里定义了一个tt变量,然后通过tt调用方法multiply(),后面的call(3)大概就是调用的意思。

> tt=eth.contract(test.abi).at("0xd26db0df7644ed6b1e46839273591bcd67cbcefd")
> tt.multiply.call(3)
18
  • 1
  • 2
  • 3

这个合约我们写的是一个数字乘以6,3*6结果是18,测试就调用成功了。


补充说明

查看合约的字节码和abi 
bytecode在detail的BYTECODE框框里面,点击旁边的copy按钮可复制出来,json中的object就是字节码。

{
    "linkReferences": {},
    "object": "6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006006820290509190505600a165627a7a72305820bfce4073e896a63a9888320f0d5d07c04954fdb3c0420f79e3170786b086c9ff0029",
    "opcodes": "PUSH1 0x60 PUSH1 0x40 MSTORE CALLVALUE ISZERO PUSH2 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0xB1 DUP1 PUSH2 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x60 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH1 0x3F JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xC6888FA1 EQ PUSH1 0x44 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE ISZERO PUSH1 0x4E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x62 PUSH1 0x4 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP2 SWAP1 POP POP PUSH1 0x78 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x0 PUSH1 0x6 DUP3 MUL SWAP1 POP SWAP2 SWAP1 POP JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xbf 0xce BLOCKHASH PUSH20 0xE896A63A9888320F0D5D07C04954FDB3C0420F79 0xe3 OR SMOD DUP7 0xb0 DUP7 0xc9 SELFDESTRUCT STOP 0x29 ",
    "sourceMap": "27:103:0:-;;;;;;;;;;;;;;;;;"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

abi在detail的ABI框框里面,点击旁边的copy按钮可复制出来,在remix的在线编译器中,看不到具体的abi的值,只能复制出来才能看到。案例的abi值大概是这样的

[{
    "constant": false,
    "inputs": [{
        "name": "a",
        "type": "uint256"
    }],
    "name": "multiply",
    "outputs": [{
        "name": "d",
        "type": "uint256"
    }],
    "payable": false,
    "stateMutability": "nonpayable",
    "type": "function"
}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

预估手续费

bytecode="0x6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006006820290509190505600a165627a7a72305820bfce4073e896a63a9888320f0d5d07c04954fdb3c0420f79e3170786b086c9ff0029"
查看手续费命令
web3.eth.estimateGas({data: bytecode})//bytecode就是上面定义的(注意前面需要加0x)
  • 1
  • 2
  • 3

call的原因是因为multiply函数没有添加constant。 
参考博客: 
http://www.8btc.com/ethereum-private-chain 
http://blog.csdn.net/u013096666/article/details/72765491

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值