使用 remix-ide(Browser-solidity)在 Geth 上部署智能合约

什么是智能合约

  • 简介:智能合约是存储在区块链上的一段代码,它们可以被区块链上的交易所触发,触发后,这段代码可以从区块链上读取数据或者向区块链上写入数据。

Solidity 的语言特性

  • Solidity 是 Ethereum 的一种契约型编程语言,运行在Ethereum虚拟机(EVM)之上。

  • 它的语法接近于Javascript,是一种面向对象的语言。但作为一种真正意义上运行在网络上的去中心合约,它又有很多的不同,下面列举一些:

  • 以太坊底层是基于帐户,而非UTXO的,所以有一个特殊的Address的类型。用于定位用户,定位合约,定位合约的代码(合约本身也是一个帐户)。

  • 由于语言内嵌框架是支持支付的,所以提供了一些关键字,如payable,可以在语言层面直接支持支付。

  • 存储是使用网络上的区块链,数据的每一个状态都可以永久存储,所以需要确定变量使用内存,还是区块链。

  • 运行环境是在去中心化的网络上,会比较强调合约或函数执行的调用的方式。因为原来一个简单的函数调用变为了一个网络上的节点中的代码执行。

  • 最后一个非常大的不同则是它的异常机制,一旦出现异常,所有的执行都将会被回撤,这主要是为了保证合约执行的原子性,以避免中间状态出现的数据不一致。

remix-ide (Browser-solidity)

  • Browser-solidity 是一个官方提供的一个基于浏览器的合约编译器,而且build版本会紧跟最新的 Solidity的 build 版本。

  • 可在浏览器中直接访问,地址为
    https://remix.ethereum.org

  • 源码在 github 上https://github.com/ethereum/remix-ide

  • 可安装到本地使用,如果在线编辑体验不佳。

    • 安装可采用几种方式
      • 下载安装包,安装使用。https://github.com/horizon-games/remix-app/releases
      • 通过 npm 和 node.js 安装
npm install remix-ide -g
remix-ide
  • 或者使用源码安装(wget)
git clone https://github.com/ethereum/remix-ide.git

git clone https://github.com/ethereum/remix.git # only if you plan to link remix and remix-ide repositories and develop on it.
cd remix-ide
npm install
npm run setupremix  # only if you plan to link remix and remix-ide repositories and develop on it.
npm start
  • 开发使用
    • 运行 npm start
    • 在浏览器中打开 http://127.0.0.1:8080
    • 打开 text editor 开始开发,该浏览器,当文件保存的时候,会自动刷新,编译(如果设置为手动设置为自动编译)。

使用 remix-ide 编辑、编译代码

  • 简单设置

    • 编辑器中,通过 + 、- 号,进行字体大小设置。
    • 点击新建一个文件,进行合约的编写。
  • 下面是一个简单的智能合约代码,功能是输入任何数值,都加上 2009。

pragma solidity 0.4.9;

contract mshkDemo {
     function mshkadd(uint a) public returns (address, uint b) {  
        uint resutl = a+2009;
        return (msg.sender, resutl);
    }  
}
  • 代码解释
    • 编译器版本选择,在本地打开remix-ide 后,在右侧的 Settings 选项卡中,在下拉列表中,选择 solidity 的版本 0.4.9
    • 第一行是声明使用 solidity 合约的版本号,在0.4.9版本以前,声明版本号,在版本号前要加上^,如 pragma solidity ^0.4.0
    • solidity 中的智能合约是一种类似javascript的语言,所以在语法上很像。

运行

  • 点击 Run 选项卡,设置好 Gas limit 和 Gas Price 后,点击 Create,能够创建一个测试实例,对代码进行调试。这时会在中间下面的窗口中,看到输出的信息。
  • 在 mshkadd 的右侧输入100,点击mshkadd,中间下面的 console 输出窗口会继续出现新的信息,点击 Details,能够看到输入的值和输出的值。
  • 点击 Compile 选项卡,然后点击 Publish on,会看到提示层,然后点击 Details,可以看到发布后的内容。
  • 发布以后,在上图弹出的层中我们可以看到编译后,能够通过 web3 部署的代码在 WEB3DEPLOY 中,代码如下:

var mahkdemoContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"mshkadd","outputs":[{"name":"","type":"address"},{"name":"b","type":"uint256"}],"payable":false,"type":"function","stateMutability":"nonpayable"}]);
var mahkdemo = mahkdemoContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x6060604052341561000c57fe5b5b60e48061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ee64a56014603a575bfe5b3415604157fe5b60556004808035906020019091905050609e565b604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b6000600060006107d9840190503381925092505b509150915600a165627a7a723058208fbdb1b57d864dd6c64a4880c43b12fc10e102ac0ce93221135eba28c8e1c3f50029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

将 remix-ide 中编译后的合约部署到 Geth

  • 将上面 WEB3DEPLOY 的代码粘贴到 geth javascript console 中执行。如果被成功的挖矿打包进区块,会返回。
> miner.start()
null

> null [object Object]
Contract mined! 
address: 0x702f69fe301c5d959b10fea629faf71d9ec71944 

transactionHash: 0x27ca30f885ec0c10e41728bad4317f12811b65284f7a63217f6fd1f78f4e6cea
  • 字段解释:

    • from 表示调用智能合约的帐户,代码中取的是 accounts[0]
    • data 是编译后的代码,你的代码越长,这块的字符串越多
    • gas 调用合约要扣除的 gas 单位,可以理解为以太币,gas 和 ether之间有个汇率,汇率受矿机的算率影响会有调整,在公网上,这些gas用于奖励给挖矿者。
    • address 表示已经部署智能合约的帐户地址,智能合约也相当于一个帐户。
    • transactionHash 的智能合约产生时的hash值,会永久保存到区块链条里面。
  • 输入 mahkdemo 可以看到合约的一些信息

> mahkdemo
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "mshkadd",
      outputs: [{...}, {...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  address: "0x702f69fe301c5d959b10fea629faf71d9ec71944",
  transactionHash: "0x27ca30f885ec0c10e41728bad4317f12811b65284f7a63217
  allEvents: function(),
  mshkadd: function()
}

  • 然后通过 mshkdemo.mshkadd.call 调用, 如果在挖矿的前提下:
  • 重新启动挖矿,调用合约,就可以输出正确的值了
> mahkdemo.mshkadd.call(10)
["0xf94caf51cf2aa14327e7f4b500b71e19f7b20352", 2019]

> mahkdemo.mshkadd.call(20)
["0xf94caf51cf2aa14327e7f4b500b71e19f7b20352", 2029]

> mahkdemo.mshkadd.call(30)
["0xf94caf51cf2aa14327e7f4b500b71e19f7b20352", 2039]

> mahkdemo.mshkadd.call(40)
["0xf94caf51cf2aa14327e7f4b500b71e19f7b20352", 2049]

你可能感兴趣的:(#,Ethereum,区块链从,1.0,到,3.0,的技术分享锦集及讲解)