从0开始部署一个简单的智能合约.md

in with 0 comment

参考文章

https://blog.csdn.net/sise_2022/article/details/141906093
https://learnblockchain.cn/article/7077

初始化安装

yarn global add truffle
yarn global add ganache-cli

启动ganache

ganache 是一个用来本地测试的网络,启动后会发放10个eth账户

启动:

ganache-cli

默认地址:127.0.0.1:8545

初始化一个合约项目

truffle init

创建一个合约文件

进入 contracts 目录

创建文件 SimpleStorage.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 public number;

    function store(uint256 _number) public {
        number = _number;
    }
}

创建文件

migrations/2_deploy_contracts.js

const SimpleStorage = artifacts.require("SimpleStorage");
module.exports = function(deployer) {
    deployer.deploy(SimpleStorage);
};

启动

truffle compile
truffle migrate

然后如果没有报错的话就是成功了

如果一直报错:

2_deploy_contracts.js
=====================

Deploying 'SimpleStorage'
-------------------------
*** Deployment Failed ***

"SimpleStorage" hit an invalid opcode while deploying. Try:
* Verifying that your constructor params satisfy all assert conditions.
* Verifying your constructor code doesn't access an array out of bounds.
* Adding reason strings to your assert statements.


Exiting: Review successful transactions manually by checking the transaction hashes above on Etherscan.


Error:  *** Deployment Failed ***

"SimpleStorage" hit an invalid opcode while deploying. Try:
* Verifying that your constructor params satisfy all assert conditions.
* Verifying your constructor code doesn't access an array out of bounds.
* Adding reason strings to your assert statements.

    at C:\Users\surest\AppData\Local\Yarn\Data\global\node_modules\truffle\build\webpack:\packages\deployer\src\deployment.js:330:1
Truffle v5.11.5 (core: 5.11.5)
Node v20.11.1

那么进入

truffle develop

进入后进行

compile
migrate

安装MteaMask

配置测试网络,点击左边那个,然后底部有个自定义网络

网络名称:LocaleEth
默认PRC地址:127.0.0.1:9545
货币符号:ETH
保存

选择这个网络,然后导入账号,从刚才 migrate 输出的内容中,有私钥,导入私钥

创建前端Html文件和网络交互

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>SimpleStorage 合约交互</title>
    <script src="https://cdn.jsdelivr.net/npm/web3@1.5.2/dist/web3.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        
        .container {
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        
        .input-group {
            margin-bottom: 15px;
        }
        
        input[type="number"] {
            padding: 8px;
            width: 200px;
            margin-right: 10px;
        }
        
        button {
            padding: 8px 16px;
            background-color: #4caf50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        
        button:hover {
            background-color: #45a049;
        }
        
        #result {
            margin-top: 20px;
            padding: 10px;
            background-color: #f8f9fa;
            border-radius: 4px;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1>SimpleStorage 合约交互</h1>
        <div class="input-group">
            <input type="number" id="numberInput" placeholder="输入要存储的数字" />
            <button onclick="storeNumber()">存储数字</button>
        </div>
        <button onclick="getNumber()">获取存储的数字</button>
        <div id="result"></div>
    </div>

    <script>
        let web3;
        let contract;
        const contractAddress = "0xA95C873C30532591efFFF1B5B384E54059c61292";
        const contractABI = [{
            inputs: [{
                internalType: "uint256",
                name: "_number",
                type: "uint256",
            }, ],
            name: "store",
            outputs: [],
            stateMutability: "nonpayable",
            type: "function",
        }, {
            inputs: [],
            name: "number",
            outputs: [{
                internalType: "uint256",
                name: "",
                type: "uint256",
            }, ],
            stateMutability: "view",
            type: "function",
        }, ];

        async function init() {
            if (typeof window.ethereum !== "undefined") {
                try {
                    await window.ethereum.request({
                        method: "eth_requestAccounts",
                    });
                    web3 = new Web3(window.ethereum);
                    contract = new web3.eth.Contract(contractABI, contractAddress);
                    document.getElementById("result").innerHTML = "Web3 已连接";
                } catch (error) {
                    document.getElementById("result").innerHTML =
                        "连接错误: " + error.message;
                }
            } else {
                document.getElementById("result").innerHTML = "请安装 MetaMask!";
            }
        }

        async function storeNumber() {
            try {
                const number = document.getElementById("numberInput").value;
                await contract.methods.store(number).send({
                    from: (await web3.eth.getAccounts())[0],
                });
                document.getElementById("result").innerHTML = "数字已存储: " + number;
            } catch (error) {
                document.getElementById("result").innerHTML =
                    "存储错误: " + error.message;
            }
        }

        async function getNumber() {
            try {
                const number = await contract.methods.number().call();
                document.getElementById("result").innerHTML =
                    "当前存储的数字: " + number;
            } catch (error) {
                document.getElementById("result").innerHTML =
                    "获取错误: " + error.message;
            }
        }

        // 页面加载时初始化
        window.onload = init;
    </script>
</body>

</html>

完成

Responses