web3.js与智能合约交互
智能合约示例:
pragma solidity ^0.5.2; contract Coin { uint public val; event Set(uint val); function set(uint _val) public { val = _val; emit Set(_val); } function get() public view returns (uint) { return val; } }
html页面(请先下载web3.min.js,并放置在与当前html页面同文件夹下)
<html> <head> <meta charset="UTF-8"> <title>web3.js使用</title> <script src="web3.min.js"></script> <style type="text/css"> span { display: inline-block; } </style> </head> <body> <h1>web3.js与智能合约交互</h1> <div id="info">444</div> <span> <input type="text" id="myVal"></input> <button onclick="setVal()">修改</button> </span> <script> //1、利用以太坊provider创建web3 var web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545")); //2、智能合约的abi,abi是由编译器生成的 var abi = [ { "constant": true, "inputs": [], "name": "val", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_val", "type": "uint256" } ], "name": "set", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "get", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "val", "type": "uint256" } ], "name": "Set", "type": "event" } ]; //3、根据abi获取合约 var ZombieFactoryContract = web3.eth.contract(abi); //合约地址,发布之后在以太坊上生成的合约地址 var contractAddress = "0x18b490cddf021886af0e5f3129468533c0026da2"; //4、根据合约地址获取合约实例 var ZombieFactory = ZombieFactoryContract.at(contractAddress); //5、监听合约中定义的事件, 执行UI操作,合约实例能访问合约中公共的函数以及事件 var event = ZombieFactory.Set(function(error, result) { if (error) { return } //console.log("9999"); //console.log(result.args.val.c); document.getElementById("info").innerHTML = ZombieFactory.get(); }); // function setVal(){ /** *调用合约中的函数 *方式1:不会更改状态变量的函数调用方法 ZombieFactory.get() *方式2:会更改状态变量的函数调用方法,需要发送交易 ZombieFactory.set.sendTransaction(函数参数, {from: web3.eth.accounts[0]}) */ ZombieFactory.set.sendTransaction(document.getElementById("myVal").value, {from: web3.eth.accounts[0]}); } </script> </body> </html>
--------------------------------------------
solidity语法:
a.sol合约文件
pragma solidity ^0.5.2; contract A { uint public x; uint public amount; constructor(uint _x) public payable { x = _x; } function get() public view returns (uint) { return x; } }
test.sol合约文件
pragma solidity ^0.5.2; import "./er.sol"; contract Coin { uint public val; A a; event Set(uint val); function set(uint _val) public { val = _val; a = new A(_val); emit Set(_val); } function get() public view returns (uint) { return val + a.get(); } }
--------------------
solidity的payable使用
payable
方法是让 Solidity 和以太坊变得如此酷的一部分 —— 它们修饰的函数是一种可以接收以太的特殊函数。
在以太坊中, 钱 (以太), 数据 (事务负载), 以及合约代码本身都存在于以太坊。你可以在调用函数的同时付钱给另外一个合约。
合约 OnlineStore.sol如下:
pragma solidity ^0.5.2; contract a { function get() public payable { // 检查以确定0.001以太发送出去来运行函数 require(msg.value == 0.001 ether); // 如果requiretongguo,执行函数向调用者发送数字内容 // transferSomething(msg.sender); } }
在这里,msg.value
是可以查看向合约发送了多少以太的方法,另外 ether
是一个內建单元。
这里发生的事是,一些人会从 web3.js
调用这个函数 (从DApp的前端), 像这样 :
// 假设 `OnlineStore` 在以太坊上指向你的合约: OnlineStore.get.sendTransaction({from: web3.eth.accounts[0], value: web3.toWei(0.001, 'ether')});//该函数返回一个256位的值,类似 0x3b57fabc53f0bc6d6dec107d3d0cea2e3409683cf105a2766bf867768c0d9cf1 这种
-----------------------------
合约本身也是一个账户,当我们调用合约里定义的payable函数时,就会向合约发送一定数量的以太,这些以太就保存在合约账户里,我们也可以从合约中将这些以太提取到指定账户,如下使用示例:
pragma solidity ^0.5.2; contract Coin { uint public val; event Set(uint val); address public owner; constructor() public{ owner = msg.sender; } function set(uint _val) public payable { val = _val; emit Set(_val); } function get() public view returns (uint) { return val; } function balanceOf() public view returns (uint) { return owner.balance; } function balanceOfContract() public view returns (uint) { return address(this).balance; } }
<html> <head> <meta charset="UTF-8"> <title>web3.js使用</title> <script src="web3.min.js"></script> <style type="text/css"> span { display: inline-block; } </style> </head> <body> <h1>web3.js与智能合约交互</h1> <div id="info">444</div> <div id="balance">444</div> <span> <input type="text" id="myVal"></input> <button onclick="setVal()">update</button> </span> <script> //1、利用以太坊provider创建web3 var web3 = new Web3(new Web3.providers.HttpProvider("http://127.0.0.1:7545")); //2、智能合约的abi,abi是由编译器生成的 var abi = [ { "constant": false, "inputs": [ { "name": "_val", "type": "uint256" } ], "name": "set", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "val", "type": "uint256" } ], "name": "Set", "type": "event" }, { "constant": true, "inputs": [], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "balanceOfContract", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "get", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "val", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ]; //3、根据abi获取合约 var ZombieFactoryContract = web3.eth.contract(abi); //合约地址,发布之后在以太坊上生成的合约地址 var contractAddress = "0xd6358db490163053a8a8c852c6397502278d0d97"; //4、根据合约地址获取合约实例 var ZombieFactory = ZombieFactoryContract.at(contractAddress); //5、监听合约中定义的事件, 执行UI操作,合约实例能访问合约中公共的函数以及事件 var event = ZombieFactory.Set(function(error, result) { if (error) { return } //console.log("9999"); //console.log(result.args.val.c); document.getElementById("info").innerHTML = ZombieFactory.get(); }); // function setVal(){ /** *调用合约中的函数 *方式1:不会更改状态变量的函数调用方法 ZombieFactory.get() *方式2:会更改状态变量的函数调用方法,需要发送交易 ZombieFactory.set.sendTransaction(函数参数, {from: web3.eth.accounts[0]}) */ ZombieFactory.set.sendTransaction(document.getElementById("myVal").value, {from: web3.eth.accounts[0], value: web3.toWei(0.001, 'ether')}); console.log(web3.eth.getBalance("0xa6c07AE626F0BB30Fe77f3f924c37CCa59895BAc")); } </script> </body> </html>
参考文章 https://www.jianshu.com/p/d7f620d23c5b
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】