安利C#开发以太坊区块链的教程:http://t.cn/ReYjplC,又快速学起来的可以看看,php、python、java、js这个网站上都有。

言归正传:

 

启动容器来执行geth命令

root@ubu-blockchain2:~# docker run -i blockchain101/ethereum-geth:1.6.5 geth attach http://45.32.252.88:8201
Welcome to the Geth JavaScript console!instance: Geth/01/v1.6.5-stable/linux-amd64/go1.8
coinbase: 0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a
at block: 6064 (Wed, 02 Aug 2017 01:13:50 UTC)datadir: /ethcluster/779977/data/01modules: admin:1.0 eth:1.0 net:1.0 rpc:1.0 web3:1.0

查看我们的账户和余额

eth.getBalance(eth.accounts[0])11000000000000000000
eth.getBalance(eth.accounts[1])
0
eth.accounts[0]
"0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a"
eth.accounts[1]
"0xe82e2f0a5abd8774767b9751659976f9c4f59181"

发起一笔交易

> 
eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(3,'ether')}) "0x0075da712d26aea17d6647035107f509e13eaf3d113c1577db14d4cc4216caec"

查看交易细节

>  eth.getTransaction("0x0075da712d26aea17d6647035107f509e13eaf3d113c1577db14d4cc4216caec"){blockHash: "0x3115703894dc6015c96ef4de3e5615f416498ca1f985902b38cd70e27dab8871",blockNumber: 1250,from: "0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a",gas: 90000,gasPrice: 18000000000,hash: "0x0075da712d26aea17d6647035107f509e13eaf3d113c1577db14d4cc4216caec",input: "0x",nonce: 0,r: "0x2aef2c1fa03a0fa4172d21e3383d8c0431d45ec855b9d16efdd5eb2de90c414c",s: "0xc4d530fb7902bf509fe56bfbea4861bf6cc16791afc9c9103c1a18f77407d1f",to: "0xe82e2f0a5abd8774767b9751659976f9c4f59181",transactionIndex: 0,v: "0x17cdb6",value: 3000000000000000000
}
> eth.getBalance(eth.accounts[1])3000000000000000000

验证用户0的余额

> eth.getBalance(eth.accounts[0])7999622000000000000

编写一个简单的合约

contract Sample {uint public value;function Sample(uint v){value=v;}function set(uint v){value=v;}function get() constant returns (uint){return value;}
}

在remix网页编译得到ABI接口和合约的二进制代码、

 abi=[{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"v","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"v","type":"uint256"}],"payable":false,"type":"constructor"}][{constant: true,inputs: [],name: "value",outputs: [{name: "",type: "uint256"}],payable: false,type: "function"
}, {constant: false,inputs: [{name: "v",type: "uint256"}],name: "set",outputs: [],payable: false,type: "function"
}, {constant: true,inputs: [],name: "get",outputs: [{name: "",type: "uint256"}],payable: false,type: "function"
}, {inputs: [{name: "v",type: "uint256"}],payable: false,type: "constructor"
}]

需要使用eth.contract来定义一个合约类

> sample=eth.contract(abi){abi: [{constant: true,inputs: [],name: "value",outputs: [{...}],payable: false,type: "function"}, {constant: false,inputs: [{...}],name: "set",outputs: [],payable: false,type: "function"}, {constant: true,inputs: [],name: "get",outputs: [{...}],payable: false,type: "function"}, {inputs: [{...}],payable: false,type: "constructor"}],eth: {accounts: ["0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a", "0xe82e2f0a5abd8774767b9751659976f9c4f59181"],blockNumber: 6225,coinbase: "0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a",compile: {lll: function(),serpent: function(),solidity: function()},defaultAccount: undefined,defaultBlock: "latest",gasPrice: 18000000000,hashrate: 0,mining: false,pendingTransactions: [],protocolVersion: "0x3f",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),getPendingTransactions: function(callback),getProtocolVersion: 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()
}

合约的二进制代码赋值给SampleHEX方便使用

SampleHEX="0x6060604052341561000c57fe5b60405160208061013a833981016040528080519060200190919050505b806000819055505b505b60f9806100416000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633fa4f24514604e57806360fe47b11460715780636d4ce63c14608e575bfe5b3415605557fe5b605b60b1565b6040518082815260200191505060405180910390f35b3415607857fe5b608c600480803590602001909190505060b7565b005b3415609557fe5b609b60c2565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b600060005490505b905600a165627a7a72305820208c8101070c8ba5a9b32db2bf4b8062a9ba50bc2869c39ac2297938756540e80029"

把合约代码部署上链

> thesample=sample.new(1,{from:eth.accounts[0],data:SampleHEX,gas:3000000}){abi: [{constant: true,inputs: [],name: "value",outputs: [{...}],payable: false,type: "function"}, {constant: false,inputs: [{...}],name: "set",outputs: [],payable: false,type: "function"}, {constant: true,inputs: [],name: "get",outputs: [{...}],payable: false,type: "function"}, {inputs: [{...}],payable: false,type: "constructor"}],address: undefined,transactionHash: "0xee74bcb4461c9712ec9aca96a5a3a4c3c64be1213854d519fc8e5432b554f7a1"
}

查看交易细节

> samplerecpt=eth.getTransactionReceipt("0xee74bcb4461c9712ec9aca96a5a3a4c3c64be1213854d519fc8e5432b554f7a1"){blockHash: "0xddba16545af882835fb9a69a0e5f3b9287c61664837d5ea0068b38575cb665c5",blockNumber: 6246,contractAddress: "0x7504fa9d64ab290844b82660d43b310f8fba0276",cumulativeGasUsed: 141836,from: "0x4c57e7e9c2f728046ddc6e96052056a241bdbd0a",gasUsed: 141836,logs: [],logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",root: "0xd1093ecaca9cc0d10e82a533a15feccedf7ff5c79fb3ebd9366ec0b35dbef478",to: null,transactionHash: "0xee74bcb4461c9712ec9aca96a5a3a4c3c64be1213854d519fc8e5432b554f7a1",transactionIndex: 0
}

合约命名

> samplecontract=sample.at("0x7504fa9d64ab290844b82660d43b310f8fba0276"){abi: [{constant: true,inputs: [],name: "value",outputs: [{...}],payable: false,type: "function"}, {constant: false,inputs: [{...}],name: "set",outputs: [],payable: false,type: "function"}, {constant: true,inputs: [],name: "get",outputs: [{...}],payable: false,type: "function"}, {inputs: [{...}],payable: false,type: "constructor"}],address: "0x7504fa9d64ab290844b82660d43b310f8fba0276",transactionHash: null,allEvents: function(),get: function(),set: function(),value: function()
}

合约查看功能函数get(),然后调用set()函数,再get()查看时已经改变了

samplecontract.get.call()
1> samplecontract.set.sendTransaction(9, {from:eth.accounts[0], gas:3000000})"0x822ee6fb4caceb7e844c533f7f3bc57806f7cb3676fb3066eb848cca46b2f38a"> samplecontract.get.call()9

我们再打开一个终端,打开cluster1的peer02的控制台,直接at到上一个终端部署的智能合约地址并进行set操作

root@ubu-blockchain2:~/ethereum-docker/ethereum-docker/ethereum-testnet-docker/dockercomposefiles#  docker run -i blockchain101/ethereum-geth:1.6.5 geth attach http://45.32.252.88:9201
Welcome to the Geth JavaScript console!>  abi=[{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"v","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"v","type":"uint256"}],"payable":false,"type":"constructor"}]> sample=eth.contract(abi)SampleHEX="0x6060604052341561000c57fe5b60405160208061013a833981016040528080519060200190919050505b806000819055505b505b60f9806100416000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633fa4f24514604e57806360fe47b11460715780636d4ce63c14608e575bfe5b3415605557fe5b605b60b1565b6040518082815260200191505060405180910390f35b3415607857fe5b608c600480803590602001909190505060b7565b005b3415609557fe5b609b60c2565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b600060005490505b905600a165627a7a72305820208c8101070c8ba5a9b32db2bf4b8062a9ba50bc2869c39ac2297938756540e80029"

直接把合约地址赋值并进行set操作

samplecontract=sample.at("0x7504fa9d64ab290844b82660d43b310f8fba0276")> samplecontract.get.call()9

简单的方法来了。智能合约的部署需要编译,这里用在线编译: 
https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.14+commit.c2215d46.js 
修改编译好的abi和对象名称:

这里在网上找了个代币的只能合约,可以进行充值、转账和查询,issue 函数可以向充值以太到合约账户,transfer 函数可以向其他账号发送token,getBalance 函数可以获取某个账号的token余额,代码如下:
pragma solidity ^0.4.2;
contract Token {address issuer;mapping (address => uint) balances;event Issue(address account, uint amount);event Transfer(address from, address to,uint amount);function Token() {issuer = msg.sender;}function issue(address account, uintamount) {if (msg.sender != issuer) throw;balances[account] += amount;}function transfer(address to, uint amount){if (balances[msg.sender] < amount)throw;balances[msg.sender] -= amount;balances[to] += amount;Transfer(msg.sender, to, amount);}function getBalance(address account)constant returns (uint) {return balances[account];}}
修改编译好的gas和对象名称:
varbrowser_untitled_sol_tokenContract =web3.eth.contract([{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"from","type":"address"},{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Transfer","type":"event"}]);
var token =browser_untitled_sol_tokenContract.new({from: web3.eth.accounts[0],data:'0x6060604052341561000f57600080fd5b5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b6103d2806100616000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063867904b414610054578063a9059cbb14610096578063f8b2cb4f146100d8575b600080fd5b341561005f57600080fd5b610094600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610125565b005b34156100a157600080fd5b6100d6600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101d2565b005b34156100e357600080fd5b61010f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061035c565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018057600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b5050565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561021e57600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef338383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a15b5050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b9190505600a165627a7a723058204afe007a03446d43d13ac892e6dba9d032f540a11ff427d26c22560727cbea2f0029',gas: '4300000'}, function (e, contract){console.log(e, contract);if (typeof contract.address !=='undefined') {console.log('Contract mined! address:' + contract.address + ' transactionHash: ' + contract.transactionHash);}})

此时输入合约部署的实例a_demotypes, 可以看到a_demotypes的详情。

控制台调用

> a_demotypes
{abi: [{constant: false,inputs: [{...}],name: "f",outputs: [{...}],payable: false,type: "function"}],address: "0x54ed7a5f5a63ddada3bfe83b3e632adabaa5fc2f",transactionHash: "0x69cde62bcd6458e14f40497f4840f422911d63f5dea2b3a9833e6810db64a1c9",allEvents: function(),f: function()
}

这里重点就是address表示的是合约的地址,你会发现这个和账号的信息结果一样,其实你也可以把这个合约地址看做是一个账号地址,后面我们外部调用到的就是这个合约地址。

充值
token.issue.sendTransaction(eth.accounts[0],100, {from: eth.accounts[0]});发送 token
token.transfer(eth.accounts[1], 30, {from:eth.accounts[0]})查看余额
token.getBalance()
控制台调用就不多说,和Java对象调用一样,直接调用即可

外部接口与智能合约交互 
以太坊对外提供的有很多接口JSON RPC接口,web3接口,这里我们用JSON RPC接口。 
相关API: https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendrawtransaction 
合约交互的原理 
合约的交互都是一次交易,而我们要做的就是把要调用的方法和参数按照api规定的以参数的形式向区块请求一次交易,ethereum接收到我们的请求后通过解析传递的参数来执行相关的合约代码。 
RPC接口给我们提供了俩个方法:eth_sendTransaction和eth_call。

eth_sendTransaction
Createsnew message call transaction or a contract creation, if the data field containscode.
ParametersObject - The transaction object
from: DATA, 20 Bytes - The address the transaction is send from.
to: DATA, 20 Bytes - (optional when creating new contract) The address the transaction is directed to.
gas: QUANTITY - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas.
gasPrice: QUANTITY - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas
value: QUANTITY - (optional) Integer of the value send with this transaction
data: DATA - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see Ethereum Contract ABI
nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

可以看到,如果我们创建的为合约时,我们只需要from,to(文档上写的是可选的,但是实际操作中没有to为null的话合约不能正常执行,建议还是加上,这个值就是前面我们部署合约后生成的合约address),data。Data的属性的值具体可以看Contract ABI。这里大概说下: 
Data的值相对来说不是固定的,具体怎么生成与合约的参数类型,参数数量都有关联。这里我们以部署的token合约的三个方法为例:

充值issue (address account, uint amount) 
这个方法有俩个参数,address充值账号,uint充值数量。 
根据Contract ABI,data值应该为方法名的sha3的前8个字节+参数的64字节,不够前面补充为0。 
这里方法名并不是issue (address account, uint amount)而是issue(address,uint256)的sha3值。

web3.sha3("issue(address,uint256)")
"0x867904b44b606800f6f10498e11292d04ea19bfc7fe4bc0f1695aa516381f73d"

我们往第一个账号充值10,这里的数据不是以太币,而是我们自己创建的代币。

 eth.accounts[0]
"0x0cc9684af605bae10de801218321c1336bb62946"

将10转换为16进制为

000000000000000000000000000000000000000000000000000000000000000a

那么data的数据为:

0x867904b4000000000000000000000000fdf57e81872562a6112656f961944ce821fdf7eb000000000000000000000000000000000000000000000000000000000000000a

那么最后我们调用eth_sendTransaction方法传递参数JSON对象为:

{from:0xfdf57e81872562a6112656f961944ce821fdf7eb,
to:0x7fe133950fc010ce41322d88f64f1918b9abb3a3,
data: 0x867904b4000000000000000000000000fdf57e81872562a6112656f961944ce821fdf7eb000000000000000000000000000000000000000000000000000000000000000a
}

返回:此交易的hash值,此时该交易还没有执行,只是创建,还需要矿工通过挖矿才能完成。 
调用接口方法:

JsonRpcHttpClient client = newJsonRpcHttpClient(new URL(“http://127.0.0.1:8545”));
Object result = client.invoke(methodName,params, Object.class);

通过控制台查看第一个账号已有代币:

token.getbalance(eth.accounts[0])

执行调用接口代码。返回交易hash值:

0x2013764d1c3fea680f9015353497aa5f9f8d61580a3bd0524b3613b34329c095

此时控制台输入: 

交易和充值一样,需要注意的是代币转出账号为from属性的值,代币转入账号为data属性里的值,to对应的是合约地址。 
eth_call

Executes anew message call immediately without creating a transaction on the block chain.
ParametersObject - The transaction call object
from: DATA, 20 Bytes - (optional) The address the transaction is sent from.
to: DATA, 20 Bytes - The address the transaction is directed to.
gas: QUANTITY - (optional) Integer of the gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions.
gasPrice: QUANTITY - (optional) Integer of the gasPrice used for each paid gas
value: QUANTITY - (optional) Integer of the value send with this transaction
data: DATA - (optional) Hash of the method signature and encoded parameters. For details seeEthereum Contract ABI
QUANTITY|TAG - integer block number, or the string "latest", "earliest" or "pending", see the default block parameter

这个方法返回一条信息给我们,相当于数据库的查询功能,参数也是三个,from,to,data,数据格式都是一样的。 
查询getBalance(address account) 
查询方法hash码:

 web3.sha3("getBalance(address)")
"0xf8b2cb4f3943230388faeee074f1503714bff212640051caba01411868d14ae3"

查询我们上一步充值的账号,那么传递的参数data为:

0xf8b2cb4f000000000000000000000000fdf57e81872562a6112656f961944ce821fdf7eb

eth_call方法最后参数为:

{from: 0xfdf57e81872562a6112656f961944ce821fdf7eb,
to:0x7fe133950fc010ce41322d88f64f1918b9abb3a3,
data:0xf8b2cb4f000000000000000000000000fdf57e81872562a6112656f961944ce821fdf7eb
}

注意,这个方法需要俩参数,处理一个JSONobject外,还有一个字符串参数,这俩可以为“”或者”latest”, “earliest” or “pending” 
调用接口返回一个16进制字符串: 
0x0000000000000000000000000000000000000000000000000000000000000071就是该账号的代币数量,转换为十进制为:113,与控制查询一致。

这就是一个智能合约的交互过程。是不是很简单啊。

安利两个以太坊相关的实战教程:

区块链初学者   : 以太坊 DApp 实战开发入门
区块链开发进阶:去中心化以太坊 DApp 电商平台实战开发

转载于:https://www.cnblogs.com/helloworld2018/p/8977026.html

以太坊智能合约部署与交互相关推荐

  1. 以太坊智能合约部署——一个简单的投票系统

    首先在Remix上进行测试 代码如下 pragma solidity ^0.4.16;/// @title Voting with delegation. contract Ballot {// Th ...

  2. java和以太坊交互_java类库web3j开发以太坊智能合约快速入门

    web3j简介 web3j是一个轻量级.高度模块化.响应式.类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成. 可以通过它进行以太坊 ...

  3. 以太坊智能合约开发第七篇:智能合约与网页交互

    原文发表于:以太坊智能合约开发第七篇:智能合约与网页交互 上一篇中,我们通过truffle开发框架快速编译部署了合约.本篇,我们将来介绍网页如何与智能合约进行交互. 编写网页 首先我们需要编写一个网页 ...

  4. 区块链开发(二)部署和运行第一个以太坊智能合约

    区块链开发(二)部署并运行第一个以太坊智能合约 李赫2016年8月22日 本文首发8BTC 网络上不少部署智能合约的文章,但是都有一个共同的特点,就是采用命令行的方式来部署,先是建立SOLC的编译环境 ...

  5. 使用Remix编译和部署以太坊智能合约

    链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载. 使用Remix编译和部署以太坊智能合约 Remix 是一个开源的 Solidity 智能合约开发环境,提供基本的 ...

  6. 以太坊智能合约开发第二篇:理解以太坊相关概念

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 很多人都说比特币是区块链1.0,以太坊是区块链2.0.在以太坊平台上,可以开发各种各样的去中心化应用,这些应用构成了以太 ...

  7. 区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码

    本文使用区块链平台以太坊+智能合约实现一个区块链记账的功能,具体为: 借款人和贷款人以及数额被记录在区块链中.使用区块链地址来表示借款人或者贷款人. 若一个借款人多次向一个贷款人借钱,更新所有的数额之 ...

  8. 用Visual Studio开发以太坊智能合约

    2019独角兽企业重金招聘Python工程师标准>>> 区块链和以太坊 自从我熟悉区块链.以太坊和智能合约以来,一直失眠. 我一直在阅读,阅读和阅读,最后我能够使用一些工具,他们建议 ...

  9. truffle (ETH以太坊智能合约集成开发工具) 入门教程

    truffle (ETH以太坊智能合约集成开发工具) 入门教程 前言 在你了解区块链开发之前,你有必要了解区块链的一些基础知识,什么是DApp,DApp与传统app的区别, 什么是以太坊,以太坊中的智 ...

  10. 教程 | 以太坊智能合约编程之菜鸟教程

    教程 | 以太坊智能合约编程之菜鸟教程 译注:原文首发于ConsenSys开发者博客,原作者为Eva以及ConsenSys的开发团队.如果您想要获取更多及时信息,可以访问ConsenSys首页点击左下 ...

最新文章

  1. 批量修改多目录下相同文件名的文件内容
  2. 使用PreloadJS加载图片资源
  3. puppeteer 鼠标定位滑块_监听滑块滑动或滑块随鼠标移动 | JShare
  4. 9 操作系统第二章 进程管理 管程
  5. -bash-退出_为什么这么多开发人员在找到工作之前就退出了。 请-不要。
  6. Python 基础总结 6 张图 带你学习Python
  7. scala练习:依据输入的年和月打印该月日历
  8. Servlet — 如何让服务器控制浏览器10秒后跳转到另一个页面
  9. JS/JQUERY函数库
  10. unity3D游戏制作—暗黑战神DarkGod
  11. 红米note9安卓手机 通电自启动 插数据线自动开机 进系统 执行命令自动化 执行脚本
  12. c语言窗体关机程序代码,c语言 关机程序代码
  13. Real Time Rendering 第一章 简介
  14. 笔记本电脑的计算机配置在哪里可以找到,笔记本电脑在哪里看配置
  15. npm/package.json/package-lock.json文件
  16. 作为一名程序员未来的出路究竟在哪里?
  17. 【对象存储】关于阿里云OSS踩坑记录
  18. 新一代科学计算与系统建模仿真平台MWORKS发布预告
  19. 百度云主机只能访问首页,bcloud_nginx_user.conf配置
  20. java jersey介绍

热门文章

  1. MySQL show processlist
  2. php处理post序列化,使用jQuery POST和php序列化和提交表单
  3. mac docker nginx 配置
  4. python数组堆叠_数组操作 -拼接与堆叠数组
  5. python3 socket sendall_全网最详细python中socket套接字send与sendall的区别
  6. SpringMVC路径配置
  7. 【渝粤教育】国家开放大学2018年春季 0688-22T老年精神障碍护理 参考试题
  8. 【渝粤教育】国家开放大学2018年春季 8612-22T传染病护理学 参考试题
  9. 这些Python骚操作,你知道吗?
  10. 在训练CNN时,loss稳定在log(类别数)