合约开源什么意思,合约不开源怎么调用

  

  1 、概述   

  

  1.1 前言   

  

  本文档主要通过实例指导如何在卫生部主网上发布智能合约教程。   

  

  文档阅读人员:社区开发人员、测试人员、运维人员。   

  

  1.2 学习准备   

  

  1.2.1 Solidity语言   

  

  固态是一种开源的智能合约高级语言,可以运行支持开源的以太坊虚拟机(EVM)之上。具体的语言介绍和学习入门,在以下的网址中有详细介绍:https://solidity . readthedocs . io/en/v 0 . 5 . 2/.   

  

  1.2.2 Remix   

  

  支持智能合约开发IDE,可以在浏览器中快速部署测试智能合约,支持固态语言。访问和使用地址:http://remix.ethereum.org或者http://remix.hpb.io/。   

  

  1.2.3 HPB主链接入指导   

  

  详情请前往卫生部官网的接入详情界面,会指导你如何通过RPC,SDK等方式和主链交互https://www.hpb.io/client .   

  

  1.2.4 智能合约Demo地址   

  

  https://github.com/loglos/web3-hpb-test.git   

  

  2 、开发智能合约   

  

  2.1 环境准备   

  

  2.1.1 通过在线Remix在线编译器进行智能合约开发   

  

  请访问链接进行智能合约开发http://remix.ethereum.org具体智能合约的开发请见第3章节。   

  

  2.1.2 通过下载Remix开源代码搭建本地开发环境   

  

  下载地址:https://github。com/ether eum/remix-ide   

  

  安装步骤   

  

  安装新公共管理和node.js(参见https://份文件。npmjs。com/getting-started/installing-node),然后安装do:   

  

  混合集成电路已经作为新公共管理模块:发布   

  

  新公共管理安装remix-ide -gremix-ideOr如果要克隆开源代码库库(需要先安装wget):   

  

  饭桶克隆https://github.com/ethereum/remix-ide.gitgit克隆https://github.com/ethereum/remix.git #仅当你计划链接再搅拌和混合集成电路库并在其上开发时cd remix-idenpm installnpm运行setupremix #仅当你计划链接再搅拌和混合集成电路库并在其上开发时npm启动DEVELOPING:   

  

  运行npm开始并在浏览器中打开http://127 .0 .0 .33608080。   

  

  然后打开你的文本编辑器,开始开发。保存文件时,浏览器会自动刷新。   

  

  大部分时间与其他模块(如调试器等)一起工作。)托管在再搅拌存储库中。   

  

  疑难排解建置如果您在建置套件:时遇到问题,请考虑一些事项   

  

  确保您拥有正确版本的节点、npm和nvm .您可以通过查看构建结果中的日志来找到在特拉维斯CI上测试的版本Run:   

  

  节点版本下午   

--versionnvm --versionIn Debian based OS such as Ubuntu 14.04LTS you may need to run apt-get install build-essential. After installing build-essential run npm rebuild.

  

Unit Testing Register new unit test files in test/index.js. The tests are written using tape.

  

Run the unit tests via: npm test

  

For local headless browser tests run npm run test-browser (requires Selenium to be installed - can be done with npm run selenium-install)

  

Running unit tests via npm test requires at least node v7.0.0

  

Browser Testing

  

To run the Selenium tests via Nightwatch serve the app through a local web server:

  

npm run serve # starts web server at localhost:8080Then you will need to either:

  

1.Have a Selenium server running locally on port 4444.

  

Run: npm run test-browser2.Or, install and run SauceConnect.

  

Run: sc -u <USERNAME> -k <ACCESS_KEY> (see .travis.yml for values)Run: npm run browser-test-scUsage as a Chrome Extension

  

If you would like to use this as a Chrome extension, you must either build it first or pull from the gh-pages branch, both described above. After that, follow these steps:

  

1.Browse to chrome://extensions/2.Make sure 'Developer mode' has been checked3.Click 'Load unpacked extension...' to pop up a file-selection dialog4.Select your remix-ide folderDocumentation

  

To see details about how to use Remix for developing and/or debugging Solidity contracts, please see our documentation page https://remix.readthedocs.io/en/latest/

  

2.2 使用Remix进行开发智能合约

  

2.2.1 合约准备

  

这里提供了一份发行ERC20标准token的合约代码。见文章末尾附件(1)

  

打开solidity智能合约在线编译器或者本地编辑器:

  

https://remix.ethereum.org/#optimize=true&version=soljson-v0.4.11+commit.68ef5810.js

  

粘贴代码到编辑器中,选择编译器编译版本为合约代码中指定的版本。

  

2.2.2 重新编译ERC20 Token源代码

  

重新编译ERC20源代码,然后复制编译通过的代码的ABI数据,为后续部署到HPB主链做准备。

  

点击查看详情。

  

2.2.3 发布合约到HPB主链

  

发布合约到HPB主链,有两种方式,一种是通过HPB官方提供JAVA SDK来发布;一种是通过安装节点后通过命令行来发布。

  

2.2.3.1 准备环境

  

通过JAVA SDK发布智能合约教程,请见HPB主网最佳实践之JAVA版本。

  

请查看Java最佳实践这篇文章

  

演示工程代码下载地址: https://github.com/loglos/web3-hpb-test.git

  

这里提醒开发者,需要新建合约对应的智能合约代码对应的 “.abi”和 “.bin” 文件并把以上复制的abi和bin代码复制到对应的该文件中。这里再简单讲解下关键代码。

  

源码工程下载后需要转为maven类型工程,注意在pom.xml文件中,引入了JAVA SDK的包。这里提醒下,请使用最新的2.0.3版本,修复了一些生成Java代码的缺陷。

  

<dependency><groupId>io.hpb.web3</groupId><artifactId>web3-hpb</artifactId><version>2.0.3</version></dependency>2.2.3.2 演示源码说明

  

演示的程序在这个package下面

  

package io.hpb.web3.test;ackage里面演示的Demo java类这里进行下说明:

  

UFOToken.sol:本次演示的ERC20的智能合约源码。

  

UFOToken.abi:智能合约编译后的abi源码。

  

UFOToken.bin:智能合约编译后的bin文件。

  

UFOTokenRun.java:Java生成智能合约对象类的执行类。

  

UFOToken.java:系统自动生成的智能合约映射的java源码。

  

2.2.3.3 UFOTokenRun执行说明

  

开发者可以直接执行UFOTokenRun.java里面的main方法,来进行调试。其中相关的地址的路径,请根据自身的开发环境的实际调用地址和HPB账号信息填写。

  

package io.hpb.web3.test;
import java.math.BigDecimal;import java.math.BigInteger;import java.util.Arrays;
import io.hpb.web3.codegen.SolidityFunctionWrapperGenerator;import io.hpb.web3.crypto.Credentials;import io.hpb.web3.crypto.WalletUtils;import io.hpb.web3.protocol.Web3;import io.hpb.web3.protocol.Web3Service;import io.hpb.web3.protocol.admin.Admin;import io.hpb.web3.protocol.core.DefaultBlockParameterName;import io.hpb.web3.protocol.core.methods.response.TransactionReceipt;import io.hpb.web3.protocol.http.HttpService;import io.hpb.web3.tx.ChainId;import io.hpb.web3.tx.RawTransactionManager;import io.hpb.web3.utils.Convert;import okhttp3.OkHttpClient;import io.hpb.web3.abi.datatypes.Address;import io.hpb.web3.abi.datatypes.generated.Uint256;
public class UFOTokenRun {
//发布智能合约账号的,keystore全路径,请根据实际地址来修改 private static String keyStoreAbsolutePath = "/path/UTC--2018-5cb988b9ce48fd3b5a328b582dd64f5c10d0e114"; //发布智能合约的账号密码,请使用你自己的账号和密码 private static String fromPassword = "demo111"; //发布智能合约的地址:这是目前已发布到主网的UFOToken智能合约地址,用户可以进行查询,但是不能转账,转账需要有HPB余额才能转账 private static String address = "0xfbbe0ba33812b531aced666d0bb2450216c11d11"; //开放的HPB节点URL地址,也可以自行搭建节点;此节点是HPB正式网开放的节点 private static String blockChainUrl = "http://pub.node.hpb.io/"; //系统默认参数设置 private static BigInteger GAS_PRICE = new BigInteger("18000000000");
private static BigInteger GAS_LIMIT = new BigInteger("100000000"); public static void main(String<> args) { //指定生成智能合约java映射类的package路径 String packageName = "io.hpb.web3.test"; //指定生成智能合约java映射类源码的本地存放地址 String outDirPath = "//erc20//UFO//java"; //指定智能合约源码的本地地址,这两个文件也放在本类的package下面,读者可以自行处理 String binFilePath = "//erc20//UFO//bin//UFOToken.bin"; String abiFilePath = "//erc20//UFO//bin//UFOToken.abi";

//1、通过io.hpb.web3来生成智能合约sol源码的的映射类;然后把映射的类放到对应的package中 GenContractJavaCode(packageName, binFilePath, abiFilePath, outDirPath) ;

//2、发布智能合约,并获取地址 String address = depolyUFOTokenTest; //3、得到智能合约的余额 getUFOTokenContractBalance; //查询指定地址的erc20余额 String queryAddress = "0xd8ACcED8A7A92b334007f9C6127A848fE51D3C3b"; //4、校验智能合约并打印相关的信息 checkUFOTokenContract(queryAddress); //5、转账 String toAddress = "0x6cb988b9ce48Fd3b5a328B582dd64F5C10d0E114"; transferUFOTokenContract(toAddress,"13333333000000000000000000"); //5.2 查询余额 //checkUFOTokenContract(contractAddress,toAddress); }
/** * 通过智能合约的源码.sol文件和编译后的.bin文件生成java的源码 * String packageName:java源码的packagename * String binFileName:存放智能合约bin文件地址 * String abiFileName:存放智能合约的abi文件地址 * String outDirPath :java源码输出地址 * * **/ public static void GenContractJavaCode(String packageName,String binFilePath,String abiFilePath,String outDirPath) { try { String SOLIDITY_TYPES_ARG = "--solidityTypes"; SolidityFunctionWrapperGenerator.main(Arrays.asList(SOLIDITY_TYPES_ARG, binFilePath,abiFilePath,"-p",packageName, "-o", outDirPath).toArray(new String<0>)); } catch (Exception e) { e.printStackTrace; }
}


/** * 通过编译智能合约源码得到合约映射的java类 * * **/ public static String depolyUFOTokenTest{ Credentials credentials = ; Admin admin = ;
String contractAddress = ""; try{ Web3Service web3Service = new HttpService(blockChainUrl, new OkHttpClient.Builder.build, true); admin = Admin.build(web3Service); credentials = WalletUtils.loadCredentials(fromPassword, keyStoreAbsolutePath); RawTransactionManager transactionManager=new RawTransactionManager(admin, credentials, ChainId.MAINNET);
// 1.发布 TOKEN UFOToken contract = UFOToken.deploy(admin, transactionManager, GAS_PRICE, GAS_LIMIT).send; System.out.println("合约地址:" + contract.getContractAddress); contractAddress = contract.getContractAddress; }catch (Exception e){ e.printStackTrace; } return contractAddress; } /** * 查询余额 * * **/ public static BigDecimal getUFOTokenContractBalance{ Credentials credentials = ; Admin admin = ; BigDecimal balanceWeiAmt = ;
try{ Web3Service web3Service = new HttpService(blockChainUrl, new OkHttpClient.Builder.build, true); admin = Admin.build(web3Service); BigInteger balance = admin.hpbGetBalance(address, DefaultBlockParameterName.LATEST).send.getBalance; balanceWeiAmt = Convert.fromWei(balance.toString, Convert.Unit.HPB); System.out.println(address + "账户余额:" + balanceWeiAmt); }catch (Exception e){ e.printStackTrace; } return balanceWeiAmt; } /** * 校验智能合约并打印地址ERC20余额 * * **/ public static void checkUFOTokenContract(String queryAddress){ Credentials credentials = ; Admin admin = ; try{ Web3Service web3Service = new HttpService(blockChainUrl, new OkHttpClient.Builder.build, true); admin = Admin.build(web3Service); credentials = WalletUtils.loadCredentials(fromPassword, keyStoreAbsolutePath); RawTransactionManager transactionManager=new RawTransactionManager(admin, credentials, ChainId.MAINNET); //检查合约是否可用
UFOToken contract = UFOToken.load(address, admin, transactionManager, GAS_PRICE, GAS_LIMIT); System.out.println("验证合约是否有效:" +contract.isValid ); if(contract.isValid) { BigInteger totalSupply = contract.totalSupply.send.getValue.divide(new BigInteger("1000000000000000000")); System.out.println("UFOtoken总供给量:"+totalSupply); System.out.println(address+" UFOToken余额:"+contract.balanceOf(new Address(address)).sendAsync.get.getValue.divide(new BigInteger("1000000000000000000"))); System.out.println(queryAddress+" UFOToken余额:"+contract.balanceOf(new Address(queryAddress)).sendAsync.get.getValue.divide(new BigInteger("1000000000000000000"))); }

}catch (Exception e){ e.printStackTrace; } } public String toDecimal(int decimal, BigInteger integer) { StringBuffer sbf = new StringBuffer("1"); for (int i = 0; i < decimal; i++) { sbf.append("0"); } String balance = new BigDecimal(integer).divide(new BigDecimal(sbf.toString), 18, BigDecimal.ROUND_DOWN).toPlainString; return balance; }


/** * 转账 * * **/ public static void transferUFOTokenContract(String toAddress,String toValue){ //keystore全路径 Credentials credentials = ; Admin admin = ; try{ Web3Service web3Service = new HttpService(blockChainUrl, new OkHttpClient.Builder.build, true); admin = Admin.build(web3Service); credentials = WalletUtils.loadCredentials(fromPassword, keyStoreAbsolutePath); RawTransactionManager transactionManager=new RawTransactionManager(admin, credentials, ChainId.MAINNET);
// 转账交易 UFOToken contract = UFOToken.load(address, admin, transactionManager, GAS_PRICE, GAS_LIMIT); TransactionReceipt receipt = contract.transfer(new Address(toAddress), new Uint256(new BigInteger(toValue))).send; System.out.println("交易Hash::::::"+receipt.getTransactionHash); }catch (Exception e){ e.printStackTrace; } }
}//指定使用solidity开发语言版本pragma solidity ^0.4.19;/** * @title SafeMath * @dev Math operations with safety checks that throw on error */library SafeMath { //基本的算术方法库 // function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } //除 function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } //减 function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } //加 function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; }}/** * @title ERC20Basic * @dev Simpler version of ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/179 */contract ERC20Basic { //总供给量,也就是发币总量 uint256 public totalSupply; //查询指定地址余额 function balanceOf(address who) public view returns (uint256); //推荐的转账方法可以安全写入 function transfer(address to, uint256 value) public returns (bool); //记录日志 //address indexed fromaddress indexed to, uint256 value: event Transfer(address indexed from, address indexed to, uint256 value);}/** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */contract ERC20 is ERC20Basic { //, _owner _spender查询能够从地址 _owner 提出的代币数量 function allowance(address owner, address spender) public view returns (uint256); // A-B从地址 _from 转移代币到地址 _to,必须触发 Transfer 事件 function transferFrom(address from, address to, uint256 value) public returns (bool); // _spender _value成功调用 approve 时触发 function approve(address spender, uint256 value) public returns (bool); //触发事件记录日志 event Approval(address indexed owner, address indexed spender, uint256 value);}/** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */contract BasicToken is ERC20Basic { //SafeMathLibrary, using SafeMath for uint256; // mapping(address => uint256) balances; //_valuetoken_to /** * @dev transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public returns (bool) { //require //address(0) 必须是有效地址 require(_to != address(0)); //balances: //msg.sender //发送者余额不为0 require(_value <= balances); // SafeMath.sub will throw if there is not enough balance. //发送者余额扣减 balances = balances.sub(_value); //接受者余额增加 balances<_to> = balances<_to>.add(_value); //进行交易 Transfer(msg.sender, _to, _value); return true; } //// balanceOffunctionbalanceOf(address _owner)constantreturns(uint256 balance) /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view returns (uint256 balance) { return balances<_owner>; }}/** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * @dev https://github.com/ethereum/EIPs/issues/20 */contract StandardToken is ERC20, BasicToken { mapping (address => mapping (address => uint256)) internal allowed; /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances<_from>); require(_value <= allowed<_from>); balances<_from> = balances<_from>.sub(_value); balances<_to> = balances<_to>.add(_value); allowed<_from> = allowed<_from>.sub(_value); Transfer(_from, _to, _value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public returns (bool) { allowed<_spender> = _value; Approval(msg.sender, _spender, _value); return true; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address _owner, address _spender) public view returns (uint256) { return allowed<_owner><_spender>; }}/// @title UFO Protocol Token./// For more information about this token, please visit http://www.banyanbbt.orgcontract UFOToken is StandardToken { string public name; string public symbol; uint public decimals; /** * CONSTRUCTOR * * @dev Initialize the UFO Token */ function UFOToken public { totalSupply = 10 * 10 ** 26; balances = totalSupply; name = "UFOToken"; symbol = "UFO"; decimals = 18; }}本文首发于汪晓明博客

  

http://wangxiaoming.com/

  

HPB 芯链官网

  

http://www.hpb.io/

  

汪晓明

  

HPB芯链创始人,巴比特专栏作家。十余年金融大数据、区块链技术开发经验,曾参与创建银联大数据。主创区块链教学视频节目《明说》30多期,编写了《以太坊官网文档中文版》,并作为主要作者编写了《区块链开发指南》,在中国区块链社区以ID“蓝莲花”知名。

相关文章