ganache私链部署智能合约+本地网络Dapp

参考自(3条消息) 区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用_一袋芋头的博客-CSDN博客下载了项目示例webpack之后

 

我们需要将里面的其他合约都删除,也可以直接删除这两个文件夹里的内容

 然后就可以开始正片了(当然,你得先前就安装好环境)

开启ganache私链,

为了后续实验方便,这里我们通过指定数据存放目录来确保账号等数据保持不变,采用如下命令来启动ganache-cli私链:

#ganache-cli -db  /root/MyGanacheData

 然后我们需要去创建合约,编译部署至该私链上

 首先在项目的合约目录,也就是/contract目录下创建sol文件

$ touch Voting.sol

$ gedit Voting.sol

// SPDX-License-Identifier: SimPL-2.0
pragma solidity >=0.4.18 <0.8.0;

contract Voting{
    bytes32[] public candodateList;
    mapping(bytes32 => uint8) public votesReceived;
    
    
    constructor(bytes32[] memory _candidateListName) public {
        candodateList = _candidateListName;
    }
    
    function validateCan(bytes32 _candidate) internal view returns(bool) {
        for(uint8 i = 0; i< candodateList.length; i++) {
            if(candodateList[i] == _candidate)
                return true;
        }
        return false;
    }
     
    function voteForCan(bytes32 _candidate) public {
        votesReceived[_candidate] += 1;
    }
    
    function totalVotes(bytes32 _candidate)public view returns(uint8) {
        return votesReceived[_candidate];
    }
}

然后我们进行编译,truffle compile,编译成功说明我们的.sol合约文件没有啥语法错误,并无卵用

然后基于这个sol文件来生成迁移文件      truffle create migration deploy_Voting,命令执行后会在migrations下生成迁移文件

 前面一串数字是truffle部署时所用的ID,这里没有用,不用管,继续,我们需要更改这个js,需要传入参数

// const ConvertLib = artifacts.require("ConvertLib");
// const MetaCoin = artifacts.require("MetaCoin");
const Voting = artifacts.require("Voting");

module.exports = function(deployer) {
    // deployer.deploy(ConvertLib);
    // deployer.link(ConvertLib, MetaCoin);
    // deployer.deploy(MetaCoin);
    deployer.deploy(Voting, [
        "0x4100000000000000000000000000000000000000000000000000000000000000",
        "0x4200000000000000000000000000000000000000000000000000000000000000",
        "0x4300000000000000000000000000000000000000000000000000000000000000"
    ]);
    //注意Voting部署时有参数
};

修改网络方式,修改truffle-conflig.js

module.exports = {
  networks: {
    development: {
      host: 'localhost',
      port: 8545,
      network_id: '*' // Match any network id
    }
  }
}

下面我们就可以部署合约了,truffle migrate

这是合约部署 的详细情况

 这是ganache私链的部署情况,因为一次部署就相当于是一次交易,所以会生成区块,会有交易哈希值产生,到此合约已经部署完毕,但是我们不好使用这个合约,所以我们需要写前端来方便我们使用它

在app/src/目录下写index.html和index.js文件

index.html

<!DOCTYPE html>
<html>

<head>
    <title>Voting</title>
</head>
<style>
    input {
        display: block;
        margin-bottom: 12px;
    }
</style>

<body>

    <h1>Voting App</h1>
    <p>Alice : <strong id="alice">loading...</strong> tickets</p>
    <p>Bob : <strong id="bob">loading...</strong> tickets</p>

    <label>VotoFor :</label>
    <input type="text" id="candidate" />
    <button onclick="App.voteForCan()">vote</button>
    <script src="index.js"></script>
</body>

</html>

index.js

import Web3 from "web3";
//导入Voting.json
import votingArtifact from "../../build/contracts/Voting.json";
//定义两个值,方便传参
const aInBytes32 = "0x4100000000000000000000000000000000000000000000000000000000000000";
const bInBytes32 = "0x4200000000000000000000000000000000000000000000000000000000000000";
const cInBytes32 = "0x4300000000000000000000000000000000000000000000000000000000000000";

//定义了app
const App = {
    web3: null,
    account: null,
    voting: null, //定义一个voting的实例

    //启动时需要的
    start: async function() {
        const { web3 } = this;

        try {
            // get contract instance
            const networkId = await web3.eth.net.getId();
            //要改成自己的网络
            const deployedNetwork = votingArtifact.networks[networkId];
            this.voting = new web3.eth.Contract(
                votingArtifact.abi,
                deployedNetwork.address,
            );

            // get accounts
            const accounts = await web3.eth.getAccounts();
            this.account = accounts[0];
            //先刷新一下界面
            this.ready();

        } catch (error) {
            console.error("Could not connect to contract or chain.");
        }
    },

    //start函数后还应该有哪些函数呢
    //1.refresh展示最新票数
    refresh: async function(id, nameInBytes32) {
        const { totalVotes } = this.voting.methods;
        //从区块链拿到票数
        const tickets = await totalVotes(nameInBytes32).call();
        //写到页面上去,并更新最新票数
        const element = document.getElementById(id);
        element.innerHTML = tickets.toString();
    },

    //2.ready:当网页好的时候要把票数读出来
    ready: async function() {
        try {
            this.refresh("alice", aInBytes32);
            this.refresh("bob", bInBytes32);
            this.refresh("clilly", cInBytes32);
        } catch (err) {
            console.log(err);
        }
    },

    //3.votingfor函数(中间需要展示票数的函数)
    voteForCan: async function() {
        try {
            //先获取到合约的方法
            const { voteForCan } = this.voting.methods;
            //再获取候选者名字:来自输入框
            const candidateName = document.getElementById("candidate").value;
            //拿到票数后对应加一
            if (candidateName == "Alice") {
                await voteForCan(aInBytes32).send({ from: this.account });
                this.refresh("alice", aInBytes32);
            } else {
            if (candidateName == "Bob") {
                await voteForCan(bInBytes32).send({ from: this.account });
                this.refresh("bob", bInBytes32);
            }
            else{
            if (candidateName == "Cilly") {
                await voteForCan(cInBytes32).send({ from: this.account });
                this.refresh("cilly", cInBytes32);
            }
            }
            }
        } catch (err) {
            //如果有err就打印一下
            console.log(err);
        }
    }

};

window.App = App;

window.addEventListener("load", function() {
    if (window.ethereum) {
        // use MetaMask's provider
        App.web3 = new Web3(window.ethereum);
        window.ethereum.enable(); // get permission to access accounts
    } else {
        console.warn(
            "No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live",
        );
        // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
        App.web3 = new Web3(
            new Web3.providers.HttpProvider("http://127.0.0.1:8545"),
        );
    }

    App.start();
});

然后运行

必须在App目录运行

npm run dev

 额,报错了error:0308010C:digital envelope routines::unsupported,什么依托答辩,没办法,只好上网搜解答  

export NODE_OPTIONS=--openssl-legacy-provider

临时解决问题,编译成功了,很牛逼,但是不知道为什么,用了再说

 然后去自己浏览器打开http://localhost:8080/

 可以开始使用,每次投票都会生成一个区块,保证了数据的不容篡改

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Truffle框架是一个用于以太坊智能合约开发的开发环境和工具集,Ganache则是一个用于本地测试以太坊智能合约的工具。下面是使用Truffle框架和Ganache网络进行智能合约部署的具体流程和代码。 1. 安装Truffle框架和Ganache网络 首先需要在本地安装Truffle框架和Ganache网络。可以使用npm命令进行安装: ``` npm install -g truffle npm install -g ganache-cli ``` 2. 创建Truffle项目 使用Truffle框架创建一个新的项目: ``` truffle init ``` 这将会在当前目录下创建一个名为`truffle-config.js`的配置文件和一个名为`contracts`的合约目录。 3. 编写智能合约代码 在`contracts`目录下创建一个名为`MyContract.sol`的智能合约文件,并编写合约代码。例如,创建一个简单的存储合约: ``` pragma solidity ^0.8.0; contract MyContract { uint256 private value; function setValue(uint256 newValue) public { value = newValue; } function getValue() public view returns (uint256) { return value; } } ``` 4. 配置Truffle项目 在`truffle-config.js`文件中配置Truffle项目。首先需要指定要使用的网络,这里使用Ganache网络: ``` module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*" } } }; ``` 5. 编译智能合约 使用Truffle框架编译智能合约: ``` truffle compile ``` 6. 部署智能合约 使用Truffle框架部署智能合约: ``` truffle migrate ``` 这将会将智能合约部署Ganache网络上。 7. 与智能合约交互 现在可以使用Web3.js或其他以太坊客户端库与智能合约进行交互。以下是一个使用Web3.js与上一步中部署的存储合约进行交互的示例代码: ``` const Web3 = require('web3'); const web3 = new Web3('http://localhost:8545'); const myContract = new web3.eth.Contract([{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}], '0x1234567890123456789012345678901234567890'); myContract.methods.setValue(42).send({from: '0x1234567890123456789012345678901234567890'}) .then(() => myContract.methods.getValue().call()) .then(value => console.log(value)); ``` 这段代码首先创建了一个Web3实例,并连接到Ganache网络。然后创建了一个`myContract`实例,它表示上一步中部署的存储合约。最后使用`myContract`实例调用`setValue`方法将值设置为42,并使用`getValue`方法获取当前值并输出到控制台。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值