以太坊智能合约部署与交互

简介: 启动容器来执行geth命令root@ubu-blockchain2:~# docker run -i blockchain101/ethereum-geth:1.

启动容器来执行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/01
 modules: 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.
Parameters

Object - 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.
Parameters

Object - 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,与控制查询一致。

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

转自:https://blog.csdn.net/ddffr/article/details/76549320

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

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


相关文章
|
存储 前端开发 算法
DAPP系统开发智能合约系统去中心化系统模式定制开发
去中心化,是互联网发展过程中形成的社会关系形态和内容产生形态,是相对于“中心化”而言的新型网络内容生产过程。在一个分布有众多节点的系统中,每个节点都具有高度自治的特征。节点之间彼此可以自由连接,形成新的连接单元。任何一个节点都可能成为阶段性的中心,但不具备强制性的中心控制功能。节点与节点之间的影响,会通过网络而形成非线性因果关系。这种开放式、扁平化、平等性的系统现象或结构,我们称之为去中心化。
|
JSON JavaScript 前端开发
以太坊 – 部署智能合约到Ganache
将编译好的智能合约部署到本地的Ganache区块链网络。步骤如下:更新项目的配置文件,修改网络配置连接到本地区块链网络(Ganache)。创建迁移脚本,告诉Truffle如何部署智能合约。运行新创建的迁移脚本,部署智能合约。...
1814 0
以太坊 – 部署智能合约到Ganache
|
存储 安全 区块链
智能合约DAPP系统搭建 | 区块链技术智能合约系统模式开发
智能合约是一种特殊协议,旨在提供、验证及执行合约。具体来说,智能合约是区块链被称之为“去中心化的”重要原因,它允许我们在不需要第三方的情况下,执行可追溯、不可逆转和安全的交易。
|
存储 安全 前端开发
DAPP链上智能合约游戏开发部署搭建
DAPP链上智能合约游戏开发部署搭建
|
安全 区块链 数据安全/隐私保护
基于以太坊的智能合约Fomo3D游戏开发规则部署
基于以太坊的智能合约Fomo3D游戏开发规则部署
|
JSON 前端开发 编译器
链上DAPP系统开发|DApp智能合约开发搭建技术
合约可以调用其他合约,只需知道地址和ABI,我们就可以在合约内部调用其他合约,需要注意的是,调用合约也是事务性操作,因此,你不需要通过手动管理异步操作的方式来等待返回结果。在合约内部调用其他合约需要消耗额外的Gas费用。
链上DAPP系统开发|DApp智能合约开发搭建技术
|
人工智能 算法 区块链
DAPP智能合约去中心化开发(稳定版)丨DAPP智能合约去中心化系统开发(详情及逻辑)丨DAPP智能合约去中心源码系统
  人工智能(Artificial Intelligence,简称AI)是指计算机系统在完成类似人类智力所需的任务时所表现出来的能力。它是一种复杂的技术,通过将大量的数据输入到算法中进行学习,不断调整和改进自己的算法,从而不断优化其性能。
|
区块链
DAPPQ去中心化智能合约开发正式版丨DAPP去中心化智能合约系统开发(开发方案)丨DAPP智能合约去中心化系统源码
Artificial intelligence technology is one of the core technologies in the era of intelligent industry.Artificial intelligence technology includes machine learning,deep learning,natural language processing,computer vision,and so on.The application of these technologies enables machines to learn,under
|
区块链
DAPP智能合约系统丨DAPP智能合约系统开发成功案例分析丨DAPP智能合约源码平台
QueryContract(contractName,method string,kvs[]*common.KeyValuePair,timeout int64)(*common.TxResponse,error)
|
存储 JavaScript Ubuntu
Dapp系统开发智能合约部署技术
在这个例子中,我们只是调用了web3.eth.accounts,然后将返回结果的第一个账号作为这个合约的所有者(即将合约部署到区块链上的账号)。也就是说,即便你更新了合约,又重新部署了一次,之前的合约仍然会原封不动地留在区块链上,并且其中存储的数据也不会受到丝毫影响,新部署的代码会创建一个全新的合约实例。首先,准备开发环境,学习在开发环境中的合约编写、编译和部署流程,通过node.js控制台与区块链上的合约交互,通过一个简单的网页与合约交互,在页面上提供投票功能并显示候选项及相应的票数。
Dapp系统开发智能合约部署技术