目录

使用 solidity 开发第一个 以太坊智能合约

前言

使用 solidity 开发一个以太坊区块链的智能合约,并且使用Dapp 进行交互。

项目源代码

最终效果



环境搭建

Nodejs 和 Ganache 请自行安装,然后使用npm安装 Truffle 智能合同框架,web3js
npm install -g truffle
npm install -g web3
  • Ganache v7.9.1 个人区块链测试环境
  • Solidity - 0.8.19 (solc-js) 以太坊区块链语言
  • Node v18.14.2
  • Truffle v5.11.5 (core: 5.11.5) 智能合约开发框架
  • Web3.js v1.10.0

智能合约内容

我们要实现在智能合约中存储和检索一个字符串值 setGreeting() 设置值, getGreeting() 获取值

Truffle 创建项目


mkdir sc-demo # 创建目录 truffle init # 项目初始化

初始化项目会生成3个文件夹和一个 配置文件

  • contracts 合同文件
  • migrations 部署文件
  • test 测试文件
  • truffle-config.js 配置文件

Truffle 编码

使用命令创建合同文件,也可以手动创建
# 命令创建
truffle create contract HelloWorld
文件生成的路径
contracts/HelloWorld.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0; contract HelloWorld {
string public greeting; constructor() {
greeting = "Hello world!";
} function setGreeting(string memory _greeting) public{
greeting = _greeting;
} function getGreeting() public view returns (string memory ){
return greeting;
} }

Truffle 打包

修改区块链地址
truffle-config.js
// 地址是你个人区块链测试地址
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 7545, // Standard Ethereum port (default: none)
network_id: "*" // Any network (default: none)
}
# 打包命令
truffle compile

Truffle 部署

迁移文件的命名规则
Truffle要求迁移文件遵循一定的命名规则,通常是以数字开头,后跟一个描述性名称,如1_initial_migration.js、2_deploy_contracts.js等。数字用于确保迁移按正确的顺序执行。 编写部署文件
migrations/2_deploy_contracts.js
const HelloWorld = artifacts.require("HelloWorld");

module.exports = function (deployer) {
deployer.deploy(HelloWorld);
};

修改编译器版本 0.8.19

  compilers: {
solc: {
version: "0.8.19" // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
}
}
# 部署命令
truffle migrate

Truffle 测试

创建测试文件

路径 contracts/test/HelloWorld.test.js
const HelloWorld = artifacts.require("HelloWorld");

contract("HelloWorld", (accounts) => {
it("should return the initial greeting", async () => {
const instance = await HelloWorld.deployed();
const greeting = await instance.getGreeting();
assert.equal(
greeting,
"Hello, World!",
"The initial greeting is not correct"
);
}); it("should set a new greeting", async () => {
const instance = await HelloWorld.deployed();
await instance.setGreeting("Hello, Truffle!");
const greeting = await instance.getGreeting();
assert.equal(
greeting,
"Hello, Truffle!",
"The new greeting is not set correctly"
);
});
});

运行测试命令

truffle test

Dapp

使用web3js 于智能合约交互,get()获取值,set()设置值
<!DOCTYPE html>
<html> <head>
<title>Simple Storage DApp</title>
</head> <body>
<h1>Simple Storage DApp</h1>
<input type="text" id="storageValue">
<button onclick="set()">Set Value</button>
<button onclick="get()">Get Value</button>
<p id="value"></p> <script src="https://cdn.jsdelivr.net/npm/web3@1.3.6/dist/web3.min.js"></script>
<script>
const web3 = new Web3(Web3.givenProvider || "http://127.0.0.1:7545");
const contractAddress = '0x0cf35631BF8B3860c0D63Fc7eB03750566023F70'; // 使用你的合约地址替换这里 // 使用你的 abi 替换这里
const contractABI = [
{
"inputs": [],
"name": "greeting",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
},
{
"inputs": [
{
"internalType": "string",
"name": "_greeting",
"type": "string"
}
],
"name": "setGreeting",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getGreeting",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function",
"constant": true
}
] // 使用你的合约ABI替换这里 const contract = new web3.eth.Contract(contractABI, contractAddress); async function set() {
const accounts = await web3.eth.getAccounts();
const value = document.getElementById('storageValue').value;
await contract.methods.setGreeting(value).send({ from: accounts[0] });
} async function get() {
const value = await contract.methods.getGreeting().call();
document.getElementById('value').innerText = value;
}
</script>
</body> </html>

命令总结

truffle init #初始化项目

truffle create contract XX #创建合同

truffle compile # 打包

truffle migrate # 部署命令

truffle console --network development # 部署完成后,你可以通过Truffle控制台与智能合约交互

truffle test # 测试

遇到的问题

注意Solidity 0.8.20

这是因为solidity 0.8.20引入了PUSH0(0x5f)操作码,该操作码仅在ETH主网上支持,而在任何其他链上都不支持。这就是为什么其他链找不到PUSH0(0x5f)操作码并抛出此错误的原因。考虑对其他链使用0.8.19。

使用-solidity-开发第一个-以太坊智能合约的更多相关文章

  1. 以太坊智能合约 Solidity 的常用数据类型介绍

    目录 目录 1.数组 1.1.对数组的增删改查操作. 2.String.Bytes.Mapping的使用 3.Enums 和 Structs 的简单应用 4.Ether 单位和 Time 单位 5.A ...

  2. 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明

    以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明 为了让你的Ðapp运行上以太坊,一种选择是使用web3.js library提供的web3.对象.底层实 ...

  3. 以太坊智能合约介绍,Solidity介绍

    以太坊智能合约介绍,Solidity介绍 一个简单的智能合约 先从一个非常基础的例子开始,不用担心你现在还一点都不了解,我们将逐步了解到更多的细节. Storage contract SimpleSt ...

  4. 以太坊智能合约Hello World示例程序

    简介 以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开 ...

  5. 如何通过以太坊智能合约来进行众筹(ICO)

    前面我们有两遍文章写了如何发行代币,今天我们讲一下如何使用代币来公开募资,即编写一个募资合约. 写在前面 本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还 ...

  6. 深入以太坊智能合约 ABI

    开发 DApp 时要调用在区块链上的以太坊智能合约,就需要智能合约的 ABI.本文希望更多了解 ABI,如为什么需要 ABI?如何解读 Ethereum 的智能合约 ABI?以及如何取得合约的 ABI ...

  7. Go语言打造以太坊智能合约测试框架(level1)

    传送门: 柏链项目学院 Go语言打造以太坊智能合约测试框架 前言 这是什么? 这是一个基于go语言编写的,自动化测试以太坊智能合约的开发框架,使用此框架,可以自动化的部署合约,自动测试合约内的功能函数 ...

  8. rpc接口调用以太坊智能合约

    rpc接口调用以太坊智能合约 传送门: 柏链项目学院   在以太坊摸爬滚打有些日子了,也遇到了各种各样的问题.这几天主要研究了一下如何通过rpc接口编译.部署和调用合约.也遇到了一些困难和问题,下面将 ...

  9. Go语言打造以太坊智能合约测试框架(level3)

    传送门: 柏链项目学院 第三课 智能合约自动化测试 之前课程回顾 我们之前介绍了go语言调用exec处理命令行,介绍了toml配置文件的处理,以及awk处理文本文件获得ABI信息.我们的代码算是完成了 ...

  10. 使用web3.js监听以太坊智能合约event

    传送门: 柏链项目学院 使用web3.js监听以太坊智能合约event   当我们在前端页面调用合约时发现有些数据不会立即返回,这时还需要再调用更新数据的函数.那么这样的方法使用起来非常不便,监听ev ...

随机推荐

  1. Spring Security入门教程 通俗易懂 超详细 【内含案例】

    Spring Security的简单使用 推荐 Java 常见面试题 简介 SSM 整合 Security 是比较麻烦的,虽然Security的功能比 Shiro 强大,相反却没有Shiro的使用量多 ...

  2. PLC开发没有前景想转行嵌入式,找个培训机构还是自学?

    0. 粉丝提问 把粉丝的情况和问题总结起来,主要以下几点: 这位粉丝19年毕业,25岁,专业是是自动化,之前从事plc开发,现在在自学单片机,想转行做Linux相关开发 犹豫是自学还是报线下培训班? ...

  3. 增删demo中,React开发中,Vue思维导致的踩坑

    .push等操作,无法监听数据的更新,必须使用setState() state最好写在构造函数中,这是个好习惯 不要什么状态的获取都放在didmount,构造函数里面获取状态也是一个不错的选择

  4. Docker 优化NUXT镜像体积

    FROM node:xxx-alpine # 环境变量赋值 ENV 参数名 参数值 RUN mkdir -p /app COPY ./app/package.json /app/package.jso ...

  5. .NET 8.0 文档管理系统网盘功能的实现

    前言 大家好,今天推荐一个文档管理系统Dorisoy.Pan. Dorisoy.Pan 是一个基于 .NET 8 和 WebAPI 构建的文档管理系统,它集成了 Autofac.MediatR.JWT ...

  6. 006.MinIO基础使用

    图形界面基础使用 bucket bucket创建 图形界面创建bucket. 特性: Versioning 开启版本控制,开启版本控制则允许在同一键下保持同一对象的多个版本. Object Locki ...

  7. SQL Server – Transaction & Isolation 事务与隔离

    前言 上回在谈到 Concurrency 并发控制 时, 有提到过事务的概念. 这篇就补上它具体的实现. 以前写过相关的文章: sql server 学习笔记 (nested transaction ...

  8. Figma 学习笔记 – Keyboard Shortcut and Tips 小技巧

    参考: 10 tips to work 10x faster in Figma 15 tips to design 15X faster in Figma | Figma Tutorial 2021 ...

  9. Flutter 这一年:2022 亮点时刻

    回看 2022,展望 Flutter Forward 2022 年,我们非常兴奋的看到 Flutter 社区持续发展壮大,也因此让更多人体验到了令人难以置信的体验.每天有超过 1000 款使用 Flu ...

  10. 4Templates Bootstrap Navbars and Links

    链接 传递参数