100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【区块链】以太坊Solidity编程:合约调用与web3.js

【区块链】以太坊Solidity编程:合约调用与web3.js

时间:2022-02-19 05:54:09

相关推荐

【区块链】以太坊Solidity编程:合约调用与web3.js

以太坊Solidity编程:合约调用与Web3.js

合约部署方法

合约的编译

使用浏览器编译器Remix使用truffle编译,目前是最常用的编译方式Solc或者Web3.js编译合约,使用相对较少

基于Remix的编译部署

Remix直接编译即可部署使用remix的web3 provider形式部署也可用remix+metamask,但metamask安装需要科学上网Remix访问的时候,建议使用http,而不是https

Truffle编译

合约应该位于./contracts目录编译合约命令:truffle compileTruffle仅仅默认自上次编译后被修改过的文件,来减少不必要的编译。如果想要编译全部文件,可以使用–compile-all选项。

Truffle编译约定

Truffle需要定义的合约名称和文件名准确匹配,如文件名为MyContract.sol,那么合约文件须为如下两者之一: contract MyContract {…}library MyContract {…} Truffle文件名匹配是区分大小写的,也就是说大小写也要一致。可以通过使用import来声明依赖。Truffle将会按正确顺序依次编译合约,并在需要的时候自动关联库。编译的输出位于./build/contracts目录。如果目录不存在会自动创建。

Truffle部署

Truffle通过truffle.js指定的以太坊网络来部署,部署命令为truffle deploy,如果truffle.js有多个网络,可以使用networkc参数来指定。

Truffle配置文件

配置文件是truffle.js。位于项目的根目录下。这个文件是Javascript文件,支持执行代码来创建配置:

BUILD:这个是前端的构建配置。默认调用默认构建器。NETWORKS:指定在部署时使用哪个网络。RPC:关于如何连接到以太坊客户端的一些细节。host和port是必须的。还包括gas(部署时的Gas限制),gasPrice(部署时的Gas价格),from(移植时使用的源地址,默认是你的以太坊客户端第一个可用账户).

Truffle配置文件示例:

module.export = {networks:{development:{host:"localhost",port:8545,network_id:"*" //匹配任何network id}}};

Truffle deployer部署参数示例:

var Hello = artifacts.require("./Hello.sol");var Multi = artifacts.require("./Multi.sol");module.exports = function(deployer){//部署单个合约,不带任何构造参数deployer.deploy(Hello);//部署单个合约带有构造参数deployer.deploy(Multi,11);//部署多个合约,一些有参数,一些没有参数/*deployer.deploy([[A,arg1,arg2,...],B,[C,arg1]]);*/}

合约调用与web3.api

智能合约调用

以太坊支持通过各种方式与节点进行交互:

JSON-RPCJavaScript Consoleweb3

JSON RPC

JSON RPC可以理解为一个rest服务大部分客户端均通过JSON RPC调功能、传数据JSON RPC只是一个传输通道,以太坊还有IPC的接口。
RPC调用客户端命令

假设我们要调用客户端命令eth.getBalance(),查询地址为0x407的账号的余额,命令如下:

curl --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407","latest"],"id":1}' localhost:8123

其中,jsonrpc字段指定JSON-RPC版本号,method字段指定需要调用的api方法名,params字段为传送的参数,id为消息标识字段;

RPC调用智能合约

假设目前有部署的智能合约,地址为0x6ff93,我们要调用的合约方法签名multiply(uint256),传入的参数值为6,那么调用命令的格式如下:

curl --data{"jsonrpc":"2.0","method":"eth_sendtransaction","param":[{"from":"0xeb85a5","to":"0x6ff93","data":"0xcddddd"}],"id":8}localhost:8123

其中,from为扣除GAS账户地址,to为智能合约部署的地址,data为调用方法的签名和传入参数,编码方式为“0x”+sha3(“multiply(uint256)”).substring(0,8)+to_32bit_Hex_str(6)

RPC合约调用

直接使用RPC对智能合约的调用需要进行复杂的编码。具体规则可以参考Ethereum Contract ABI文档。实际编程中,基本都使用web3等方式,对RPC进行了友好封装。

Web3概述

与合约交互,最常用的方式就是使用web3.js library提供的web3底层实现上,它通过RPC调用与本地节点通信web3.js可以与任何暴露了RPC接口的以太坊节点连接。Web3已随truffle安装。

Web3调用合约

web3.js封装了合约调用的方法。使用可以直接使用web3.eth.contract的里的sendTransaction来修改区块链数据调用合约,可能需要from等参数,否则可能出现调用异常。

Web3 API体系

Web3-eth:以太坊区块链基本操作和智能合约相关操作。Web3-ssh:实现whisper相关操作,包括p2p和广播操作。Web-bzz:swarm协议相关,分布式存储web3-utils:Dapp 开发辅助功能

Web3版本说明

npm ls web3,使用该命令查看版本npm update web3,如果版本过低,请升级

版本文档以此为准:

https://web3.js.readthedocs.io/en/1.0/web3-eth.html

Web3初始化

// 引入web3// in node.js use: var Web3=require('web3');//如果浏览器按照了MetaMask,则会提供一个默认的web3.currentProvider//如果为空,则连接远程/本地节点var web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");

Web3常用API

web3.setProvider,设置Provider

参数:无返回值:无示例:web3.setProvider(new web3.providers.HttpProvider(‘http://localhost:8545’));

web3.toWei

按对应货币转为以wei为单位。最常用的单位为ether。示例:var value = web3.toWei(‘1’,‘ether’);

console.log(value); // “10000000000000000000”

web3.eth.account,以太坊账号

示例:web3.eth.getAccounts([callback])

web3.eth.getBalance(address[,defaultBlock] [,callback])

web3.eth.contract, 创建一个Solidity的合约对象,用来在某个地址上初始化合约。

参数:Array,一到多个描述合约的参数,事件的API对象。返回值:Object,一个合约对象。示例:var MyContract = new web3.eth.Contract(abiArray);

合约对象的方法

显示对象call。myContract.methods.myMethod([param1[,param2[,…]]]).call(options[,callback]);(不修改数据)显示调用send。myContract.methods.myMethod([param1[,params[,…]]]).send(options[,callback]);(修改数据,消耗gas)

合约调用方法代码示例:

//合约实例var contract = new web3.eth.Contract(abi,address);//callbackcontract.methods.helloWorld().call(function(error,result){colsole.log(result);});//promisecontract.methods.helloWorld().call().then(function(result)(console.log(result);));

合约对象的事件

参数: Object, 你想返回的索引值(过滤哪些日志)。如{‘valueA’,1,‘valueB’:[myFirstAddress,mySecondAddress]}。默认情况下,所有过滤项被设置为null。意味着默认匹配的是合约所有的日志。 OBject,附加的过滤选项。参见web3.eth.filter的第一个参数。默认情况下,这个对象会设置address为当前合约地址,同时第一个主题为事件的签名。 Function,(可选)传入一个回调函数,将立即开始监听,这样就不用主动调。

合约对象的事件,回调返回值:

OBject,事件对象,如下: address:String,32字节,日志产生的合约地址 args:Object,事件的参数 blockHash:String,32字节,日志所在块的哈希。如果是pending的日志,则为null。 blockNumber:Number,日志所在块的块号。如果是pending的日志,则为null。 logIndex:Number,日志在区块中的序号。如果是pending的日志,则为null。 event:String,事件名称 removed:bool,标识产生事件的这个交易是否被一处(因为孤块),或从未生效(被拒绝的交易)。 transactionIndex:Number,产生日志的交易在区块中的序号。如果是pending的日志,则为null。 transactionHash:String,32字节,产生日志的交易哈希值。

Web3.js的使用与案例

合约调用的基本流程

初始化web3,连接以太坊节点rpc服务,获得一个provider对象初始化合约的对象。合约对象的provider设置为已知初始化的web3对象。调用合约监听合约

合约调用

合约调用可以使用call或者send。myContract.methods.myMethod([param1[,param2[,…]]]).call/send(options[,callback])options可以包括from,gasPrice,gas,value。分别代表调用者地址,gas价格,消耗的最低gas,发送的以太币数量。

Web3调用合约的例子

var Web3 = require('web3');console.log(Web3.version);//设置web3对象var web3 = new Web3('http://localhost:8545');var json = require("../build/contracts/Hello.json");var abi = json["abi"];var address = "0x91ab99f3983y798cenu9eh49erjj88q3u4rjeqd903q4uytr04";//合约实例var contract = new web3.eth.Contract(abi,address);//callbackcontract.methods.helloWorld().call(function(error,result){console.log(result);});

Truffle对Web3的封装

// 1.引用编辑好的合约文件结果var json = require("./build/contracts/MyContract.json");// 2.将合约转为合约抽象层实例var contract = require("truffle-contract");var MyContract = contract(json);// 3. 设置合约抽象层实例的web3 providerMyContract.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));// 4. 开始使用MyContract.deployed().then(function(deployed){return deployed.someFunction();});

Truffle封装web3的优点

对以太坊的智能合约做了更好的抽象,使用简单同步的交易:可以确保在交易生效之后再继续执行其他操作。返回Promise:每个封装的合约函数会返回Promise,可以对它进行.then操作,避免了回调地狱(callback hell)问题。为交易提供了默认参数:例如from或gas。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。