【区块链】利用Node.js开发与合约交互的Web界面

利用Node.js开发与合约交互的Web界面

参考地址:here and here

零、在私有链上部署合约

// 本文中用到的MetaCoin合约
pragma solidity ^0.4.2;

contract MetaCoin {
    mapping (address => uint) balances;

    event Transfer(address indexed _from, address indexed _to, uint256 _value);

    function MetaCoin() {
        balances[tx.origin] = 10000;
    }

    function sendCoin(address receiver, uint amount) returns(bool sufficient) {
        if (balances[msg.sender] < amount) return false;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Transfer(msg.sender, receiver, amount);
        return true;
    }

    function getBalance(address addr) returns(uint) {
        return balances[addr];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

一、新建一个项目

新建一个node.js项目并初始化

$ mkdir web3test && cd web3test
$ npm init
  • 1
  • 2

二、导入web3.js

npm install web3 --save
  • 1

三、创建web3对象

var Web3 = require("web3");
//创建web3对象
var web3 = new Web3();
// 连接到以太坊节点
web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));
  • 1
  • 2
  • 3
  • 4
  • 5

可以测试一下:

var version = web3.version.node;
console.log(version);
==>
在app目录下,终端输入:
prodeMacBook-Pro:web3test pro$ node app.js
输出:
Geth/linoy/v1.6.5-stable-cf87713d/darwin-amd64/go1.8.3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

四、调用合约

部署合约: 
私有链上查看地址,abi可以通过here获取

var abi = [{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}];

var address = "0x6a0a87bd4da65b39a1b27597edb1a5b505a55a0b";

var metacoin = web3.eth.contract(abi).at(address);
  • 1
  • 2
  • 3
  • 4
  • 5

调用合约:

/* 查看账户余额 */
var account_one = web3.eth.accounts[0];
var account_one_balance = metacoin.getBalance.call(account_one);
console.log("account one balance: ", account_one_balance.toNumber());
===>
终端查看:
prodeMacBook-Pro:web3test pro$ node app.js
account one balance:  10000

/* 转账操作 */
var account_one = web3.eth.accounts[0];
var account_two = web3.eth.accounts[1];

var txhash = metacoin.sendCoin.sendTransaction(account_two, 100, { from: account_one });

var myEvent = metacoin.Transfer();
myEvent.watch(function (err, result) {
    if (!err) {
        if (result.transactionHash == txhash) {
            var account_one_balance = metacoin.getBalance.call(account_one);
            console.log("account one balance after sendCoin:", account_one_balance.toNumber());
        }
    } else {
        console.log(err);
    }
    myEvent.stopWatching();
});
====>
这里可能会遇到错误:Error: authentication needed: password or unlock
原因是账户没有解锁:在终端,personal.unlockAccount(user1, "123456")
然后再次尝试可以看到:
account one balance:  10000
account one balance after sendCoin: 9900
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

创建账户:

var account_three = web3.personal.newAccount("123456");
console.log(account_three);
  • 1
  • 2

五、与web界面交互

1 . 安装express

查看:here

npm install express --save
  • 1

2 . 导入BigNumber.js

处理大数字需要使用BigNumber库

npm install --save bignumber.js
===>
var BigNumber = require('bignumber.js');
  • 1
  • 2
  • 3

3 . 调用合约

a. call

var returnValue = metacoin.getBalance.call(address).toString();
  • 1

b. sendTransaction

var txhash = metacoin.sendCoin.sendTransaction(address_b, trans_value, {from:address_a});
  • 1

4 . 界面

 
 

六、代码部分

1 . app.js代码

/* 现连接到geth节点,并获取已部署合约的引用 */
var express = require("express");  
var app = express();  
var server = require("http").createServer(app);
var io = require("socket.io")(server);
var BigNumber = require('bignumber.js');

app.use(express.static("public"));

app.get("/", function(req, res){
    res.sendFile(__dirname + "/index.html");
})

// 现连接到geth节点
var Web3 = require("web3");
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));  


/* 部署合约 */
var abi = [{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}];

var address = "0x6a0a87bd4da65b39a1b27597edb1a5b505a55a0b";

var metacoin = web3.eth.contract(abi).at(address);

app.get("/register", function(req, res){

    //获取输入的密码
    var password = req.query.password;
    //创建账户
    var account = web3.personal.newAccount(password);
    res.send(account);

})

app.get("/getBalance", function(req, res){

    var address = req.query.address;

    //获取address的余额
    var returnValue = metacoin.getBalance.call(address).toString();
    res.send(returnValue);

})

app.get("/sendcoin", function(req, res){

    var address_a = req.query.address_a;
    var address_b = req.query.address_b;
    var trans_value = req.query.trans_value;

    //转账操作
    var txhash = metacoin.sendCoin.sendTransaction(address_b, trans_value, {from:address_a});
    res.send(txhash);

})
server.listen(8080);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

2 . html代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>转账操作</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <div>
        <div> 
            <h3>注册:</h3><br>
            <label for="identity">请输入密码:</label><input type="text" id="password" ></input>
            <button type = "submit"  onclick="register()">注册</button>
            <p id = "address_test">地址:</p>
        </div>
        <div> 
            <h3>查询余额:</h3><br>
            <label for="identity">请输入地址:</label><input type="text" id="address" ></input>
            <button type = "submit" onclick="getBalance()">查询余额</button>
            <p id = "address_balance">余额:</p>
        </div>  
        <div>
            <h3>转账</h3>
            <label for="identity">转出用户地址</label><input type="text" id="address_a" ></input>
            <br><label for="identity">转入用户地址</label><input type="text" id="address_b" ></input>
            <br><label for="identity">金额</label><input type="text" id="trans_value" ></input>
            <button type = "submit"  onclick="sendcoin()">确定</button>
            <p id = "tx_hash">交易:</p>
        </div>

    </div>
    <script type="text/javascript" src="/sha1.min.js"></script>
    <script type="text/javascript" src="/jquery.min.js"></script>
    <script type="text/javascript" src="/socket.io.min.js"></script>
    <script type="text/javascript" src="/main.js"></script>
    <script type="text/javascript" src="/bignumber.js"></script>

</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

3 . main.js代码

function register()
{
    var password = document.getElementById("password").value;

    $.get("/register?password=" + password, function(data){
        if(data == "Error")
        {
            $("#address_test").text("An error occured.");
        }
        else
        {
            $("#address_test").html("地址: " + data);
        }
    });
}

function getBalance()
{
    var address = document.getElementById("address").value;

    $.get("/getBalance?address=" + address, function(data){

        if(data == "Error")
        {
            $("#address_balance").text("An error occured.");
        }
        else
        {
            $("#address_balance").html("余额: " + data);
        }
    });
}

function sendcoin()
{
    var address_a = document.getElementById("address_a").value;
    var address_b = document.getElementById("address_b").value;
    var trans_value = document.getElementById("trans_value").value;

    var tx_hash = document.getElementById("tx_hash").value;

    //转账
    $.get("/sendcoin?address_a=" + address_a + "&address_b=" + address_b + "&trans_value=" + trans_value, function(data){

        $("#tx_hash").html("交易: " + data);

    });

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值