【以太坊开发】如何开发一个编译以太坊智能合约并且发布的平台(二)

接上一章的内容,这篇介绍 deploy相关和结果演示。

deploy一个合约的过程中,需要计算发布的消耗和nonce值。

当进行每笔交易时,发送人设定Gas Limit 和Gas Price,将 Gas Limit*Gas Price ,就得到了ETH交易佣金的成本。

nonce:以太坊要求一个账户的每笔交易有一个连续的计数。每个节点将根据计数顺序严格执行来自一个用户的交易。

app.js中有下面两个函数:

var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

function etherSpentInPendingTransactions(address, callback)
{
    web3.currentProvider.sendAsync({
          method: "txpool_content",
           params: [],
           jsonrpc: "2.0",
           id: new Date().getTime()
    }, function (error, result) {
        console.log(result)
        if(typeof(result.result.pending)!="undefined" && result.result.pending)
        {
            if(result.result.pending[address])
            {
                var txns = result.result.pending[address];
                var cost = new BigNumber(0);

                for(var txn in txns)
                {
                    cost = cost.add((new BigNumber(parseInt(txns[txn].value))).add((new BigNumber(parseInt(txns[txn].gas))).mul(new BigNumber(parseInt(txns[txn].gasPrice)))));
                }

                callback(null, web3.fromWei(cost, "ether"));
            }
            else
            {
                callback(null, "0");
            }
        }
        else
        {
            callback(null, "0");
        }
    })
}

上面函数的流程:

1 使用sendAsync异步调用JSON PRC,调用的方法是 :txpool_content,这个方法用于查询交易池中待处理的交易,返回的结果属性有pending和queqed。想了解这个函数可以查看:https://github.com/ethereum/go-ethereum/wiki/Management-APIs#txpool_content

2  通过返回结果的属性 pending和账户的地址获取所以交易:

var txns = result.result.pending[address];对交易的结果进行循环,累加每个交易的value和gas消耗,就是所有将要打包到下个块的交易的总消耗。

在介绍一下getNonce函数:
function getNonce(address, callback)
{
    web3.eth.getTransactionCount(address, function(error, result){
        var txnsCount = result;

        web3.currentProvider.sendAsync({
              method: "txpool_content",
              params: [],
              jsonrpc: "2.0",
              id: new Date().getTime()
        }, function (error, result) {
            if(result.result.pending)
            {
                if(result.result.pending[address])
                {
                    txnsCount = txnsCount + Object.keys(result.result.pending[address]).length;
                    callback(null, txnsCount);
                }
                else
                {
                    callback(null, txnsCount);
                }
            }
            else
            {
                callback(null, txnsCount);
            }
        })
    })
}

eth中每个交易的nonce是累加的,它是把挖出的交易总数和待定的交易总数加起来得到的。

所以对于deploy函数来说,只需要利用上面两个函数构造交易的消耗cost和nonce值然后调用sendRawTranstaction,当然还需要对交易签署,需要提供秘钥,所以界面设计也会需要账户秘钥。代码如下:

app.get("/deploy", function(req, res){
    var code = req.query.code;
    var arguments = JSON.parse(req.query.arguments);
    var address = req.query.address;

    var output = solc.compile(code, 1);

    var contracts = output.contracts;

    for(var contractName in contracts)
    {
        var abi = JSON.parse(contracts[contractName].interface);
        var byteCode = contracts[contractName].bytecode;

        var contract = web3.eth.contract(abi);

        var data = contract.new.getData.call(null, ...arguments, {
            data: byteCode
        });
        console.log(data);
        console.log(web3.eth.defaultAccount)
        var gasRequired = web3.eth.estimateGas({
            from:address,
            data: "0x" + data
        });

        web3.eth.getBalance(address, function(error, balance){
            var etherAvailable = web3.fromWei(balance, "ether");
            etherSpentInPendingTransactions(address, function(error, balance){
                etherAvailable = etherAvailable.sub(balance)
                if(etherAvailable.gte(web3.fromWei(new BigNumber(web3.eth.gasPrice).mul(gasRequired), "ether")))
                {
                    getNonce(address, function(error, nonce){
                        var rawTx = {
                            gasPrice: web3.toHex(web3.eth.gasPrice),
                            gasLimit: web3.toHex(gasRequired),
                            from: address,
                            nonce: web3.toHex(nonce),
                            data: "0x" + data
                        };

                        var privateKey = ethereumjsUtil.toBuffer(req.query.key, ‘hex‘);
                        var tx = new ethereumjsTx(rawTx);
                        tx.sign(privateKey);

                        web3.eth.sendRawTransaction("0x" + tx.serialize().toString(‘hex‘), function(err, hash) {
                            res.send({result: {
                                hash: hash,
                            }});
                        });
                    })
                }
                else
                {
                    res.send({error: "Insufficient Balance"});
                }
            })
        })

        break;
    }
})

到这里基本流程已经很清晰了。具体的代码可以到git上下载:https://github.com/figo050518/deployContract

配置app.js的web3地址。

进入项目根目录 执行 npm install

node app.js 启动前端服务。

我定义的端口是7070。下面是笔者执行的截图:

到这里就完成了一个编译 部署合约的平台,前端页面没有过多介绍,读者可以看下源码。

原文地址:https://www.cnblogs.com/gzhlt/p/10043113.html

时间: 2024-11-09 10:23:09

【以太坊开发】如何开发一个编译以太坊智能合约并且发布的平台(二)的相关文章

Windows下以太坊集成开发环境(Remix-IDE)搭建与智能合约的简单应用

前面我们介绍了在以太坊平台下开发区块链私有链的过程,以及在私有链下进行挖矿的操作,而随着区块链技术的发展,区块链技术已不仅限于比特币的应用,未来将重在着眼于向其他领域的扩展推广,以此开启区块链2.0以智能合约为代表的时代.本文选用remix作为开发应用平台,配合geth客户端实现与以太坊网络的交互,下一篇文章则改用truffle和ganache搭建开发框架(这是后话). 本文分为remix-ide搭建和智能合约部署应用两部分. 一.remix-ide搭建 [准备工作] 1.安装Node.js.N

如何编写一个可升级的智能合约

区块链信任基础的数据不可修改的特性,让它传统应用程序有一个很大的不同的地方是一经发布于区块链上就无法修改(不能直接在原有的合约上直接修改再重新发布). 写在前面 阅读本文前,你应该对以太坊.智能合约及Solidity语言有所了解,如果你还不了解,建议你先看以太坊是什么 当智能合约出现bug 一方面正式由于智能合约的不可修改的特性,因为只要规则确定之后,没人能够修改它,大家才能够信任它.但另一方面,如果规则的实现有Bug, 可能会造成代币被盗,或是调用消耗大量的gas.这时就需要我们去修复错误.

2018年以太坊智能合约开发语言Solidity最佳IDEs

Solidity是一种以智能合约为导向的编程语言.这是一种只有四年的年轻语言,旨在帮助开发基于以太坊数字货币的智能合约. 理解它官方文档应该是学习Solidity的最佳来源:solidity.readthedocs.io 想在以太坊的网络上建立自己的加密货币吗?想拥有自己的初始代码产品吗?以下是您今天可以使用的最佳Solidity IDE. Remix IDE Remix IDE是基于浏览器的,并且集成了编译器.没有服务器端组件. 官网: https://remix.ethereum.orggi

第一行代码:以太坊(2)-使用Solidity语言开发和测试智能合约

智能合约是以太坊的核心之一,用户可以利用智能合约实现更灵活的代币以及其他DApp.不过在深入讲解如何开发智能合约之前,需要先介绍一下以太坊中用于开发智能合约的Solidity语言,以及相关的开发和测试环境. 智能合约就是运行在以太坊上的程序.客户端可以通过Web3.js API调用智能合约,而智能合约本身又可以直接访问以太坊网络,也就是说,智能合约前面连接着客户端,后面连接着以太坊网络,起到了承前启后的作用,而且通过智能合约,可以让整个以太坊网络更灵活,可控性更强.其实智能合约的作用相当于微软O

以太坊智能合约及应用开发简介

在这个入门教程中我们将建立以太坊应用开发环境并学习编写一个投票智能合约. 在这个教程中,让我们构建一个简单的"Hello World!" 应用程序, 这是一个投票应用程序. 该应用程序非常简单,它所做的只是初始化一组候选人,让任何人投票给候选人,并显示每个候选人收到的总票数. 我有意避免使用任何DAPP框架构建这个应用程序,因为框架抽象掉很多细节,你不了解系统的内部.此外,当你使用框架时,将对框架所做的繁重工作有更多的体会! 1. 设置开发环境 我们使用一个模拟的内存区块链(ganac

深入以太坊智能合约 ABI

开发 DApp 时要调用在区块链上的以太坊智能合约,就需要智能合约的 ABI.本文希望更多了解 ABI,如为什么需要 ABI?如何解读 Ethereum 的智能合约 ABI?以及如何取得合约的 ABI? 数字猫合约 ABI ABI(Application Binary Interface) 如果理解 API 就很容易了解 ABI.简单来说,API 是程序与程序间互动的接口.这个接口包含程序提供外界存取所需的 functions.variables 等.ABI 也是程序间互动的接口,但程序是被编译

第18讲 | 智能合约与以太坊

在前面的文章里,我们介绍了区块链的核心技术,也穿插介绍了一些项目.然而每个区块链都有自己的特色,接下来我们将针对每个项目进行详细讲解.今天我们就来讲讲智能合约和以太坊项目. 今天我们从智能合约这个概念入手,聊聊什么是以太坊项目以及它的发展历史.最后还会介绍几款钱包给你,希望通过今天文章的讲解,你也可以尝试在以太坊上编写简单的智能合约. 智能合约的概念 不同于法律意义上的合约概念,区块链领域的合约表达的是可以“自治自理”的 计算机协议,这套协议具有自我执行.自我验证的属性. 如果完全从技术角度来看

第一行代码:以太坊(3)-使用更多的工具编写和测试智能合约

<第一行代码:以太坊>开始连载了 在上文中已经使用了Remix环境运行和测试了本书编写的第一个智能合约程序,不过编写和测试智能合约的测试方式很多,例如,在testrpc环境测试:在Intellij IDEA集成开发环境中用Solidity语言编写智能合约:在纯Web环境中测试智能合约:使用AJAX方式测试智能合约等.本文将详细介绍这些用于编写和测试智能合约的方法. 1.安装本地remix环境(Windows.Mac OS X和Linux) 在本节使用Remix环境运行和测试了Calc智能合约,

经典:浅谈以太坊智能合约的设计模式与升级方法

目录 1. 最佳实践 2. 实用设计案例 2.1 控制器合约与数据合约: 1->1 2.2 控制器合约与数据合约: 1->N 2.3 控制器合约与数据合约: N->1 2.4 控制器合约与数据合约: N->N 2.5 总结 3. 升级 3.1 控制器合约升级,数据合约不升级 3.2 控制器合约不升级,数据合约升级 3.3 控制器合约升级,数据合约升级 4. 数据迁移 4.1 硬编码迁移法 4.2 硬拷贝迁移法 4.3 默克尔树迁移法 以太坊EVM是当前区块链行业应用最为广泛的虚拟机