【以太坊傻瓜教程】在私链上发布第一个合约

2023-10-30

【以太坊傻瓜教程】在私链上发布第一个合约


教程简介:

本教程将介绍如何编写合约,编译合约以及如何将合约发布到自己的私链上并调用。


开发环境:

本教程开发环境:


编写合约:

新建一个文本文件,在此文件中键入如下代码:

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) {
        storedData = x;
    }

    function get() constant returns (uint) {
        return storedData;
    }

}

代码第一行是用来向编译器声明当前合约是采用0.4版本Solidity语法编写。这个声明的目的是保证合约针对编译器的向后兼容性。后面的代码是合约主体。声明了一个“状态变量”(State Variable)叫做storedData类型为uint(此处的uint是256位值),此变量值记录在区块链数据库中。合约中的“状态变量”有点类似于c++中的静态成员变量。然后声明了两个函数set和get,分别用来设置与获取上面声明的“状态变量”值。

将此文本文件保存,并重命名为 SimpleStorage.sol。
这里写图片描述


编译合约:

打开Windows命令行输入如下命令

echo var contractContent = > SimpleStorage.js
solc --combined-json abi,bin,interface SimpleStorage.sol >> SimpleStorage.js

此步骤的主要目的是生成一个javascript脚本,脚本的目的是初始化一个叫contractContent变量,此变量以字符串形式记录了编译好的合约脚本。第二个命令是使用solidity的编译器,将我们的合约SimpleStorage进行编译,并生成ABI,合约字节码,和接口描述。将这些信息打包为json格式。

运行完这一步我们得到了一个javascript脚本,SimpleStorage.js
这里写图片描述

此脚本后面会在geth中执行,这样就可以将编译好的合约脚本巧妙地传到了geth可控制台内。此步骤主要是因为在geth1.6后内部取消了eth.compile.Solidity的编译函数


发布合约:

启动geth控制台,在Windows命令行中输入如下命令

geth --datadir "E:\EthDBSpace\PrivChain" --jspath "D:\workspace\solidity\" console      

–datadir 选项是用来指定eth数据路径的,这里指定是的我们之前建好的私链数据路径。关于如何构建私链,可参见上一课“如何创建私链”(http://blog.csdn.net/weixin_40401264/article/details/78095222)。
–jspath 选项是用来指定javascript存放目录的。这里我们指定为我们刚才编译好的SimpleStorage.js所在目录。
console 命令用来指示geth打开命令行

经过一阵初始化,进入geth命令行。显示结果如下:
这里写图片描述

载入编译好的合约,在geth命令行中输入:

loadScript("SimpleStorage.js")

此命令会载入并执行SimpleStorage.js。结果就是多了一个新变量contractContent,此变量记录了编译好的合约。

查看编译好的合约是否成功,可直接在geth命令行键入变量名查看变量内容

contractContent

结果如下,载入成功。

这里写图片描述

创建contract对象,在geth命令行中键入:

var contractTemplate=web3.eth.contract(JSON.parse(contractContent.contracts["SimpleStorage.sol:SimpleStorage"].abi))

上面代码的含义为:采用contractContent的”SimpleStorage.sol:SimpleStorage”合约的ABI来创建一个contract对象。所谓contract的对象可以理解为一个合约模板,后面会根据此模板来创建合约实例。

发布合约前需要获得发布合约的gas预估,在geth命令行中键入

var gasValue = eth.estimateGas({data:"0x"+contractContent.contracts["SimpleStorage.sol:SimpleStorage"].bin})

在发布合约前需要解锁账户,因为会用到里面的钱。在geth命令行中键入

personal.unlockAccount(eth.accounts[0])

发布合约,在geth命令行中键入

var contractInst = contractTemplate.new({ from: eth.accounts[0], data: "0x" + contractContent.contracts["SimpleStorage.sol:SimpleStorage"].bin,gas:gasValue},
      function (e, contract) {
            console.log(e, contract);
           if (typeof contract.address !== 'undefined') {
              console.log('Contract mined! address: ' + contract.address + 'transactionHash: ' + contract.transactionHash);
           }
      }
);

上面代码的含义为:调用contract.new函数来发布合约,返回一个合约实例。
contract.new函数的签名为:contract.new([arg0][,arg1]…[,transactionObject][,callback])
前面若干形参是构造函数参数。第二个参数填交易描述。对于发布合约,from填写要发布合约的账户,to参数无需填写,data参数填写编译好的合约的字节码文本, gas填写发布合约的gas值,此处我们填写的上面系统评估个gas值gasValue。第三个参数填异步回调。这个回调函数会在发布合约成功后调用。我们这里的回掉是在合约发布后在控制台上打印合约发布地址及交易Has。在以太坊中js回调用了类Node.js的error-first callback形式的回调.
关于Error-First Callback参见
http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/

合约发布命令执行成功后,控制台会显示交易已被提交
这里写图片描述

挖矿来让合约发布到私链区块中。

miner.start()

合约提交成功后,结果如下:
这里写图片描述

可以看到我们的回调被调用,打印出了合约的地址:0x171d64d78f753d2c95f4efba6799a0cc6dc8c5a7

结束挖矿:

miner.stop()

调用合约函数:

下面我们调用set来为状态变量storedData赋值。由于我们的set函数是要改写链上数据的,所以需要使用sendTransaction来调用。为了使用sendTransaction来调用链上合约,首先我们需要获得函数的签名的函数选择器(Function Selector)。将函数签名传入sha3函数生成hash256,hash的前4个字节即函数选择器的值。
在geth命令行输入如下命令,获取set函数哈希:

web3.sha3("set(uint256)")

其中函数签名的参数列表只需写参数类型,注意参数列表不要有空格。
其中参数类型必须准确到字长,比如当前合约的storedData变量为uint,在solidity中uint类型等同于uint256,所以这里要填uint256

算set函数哈希结果如下:

这里写图片描述

哈希值为0x60fe47b16ed402aae66ca03d2bfc51478ee897c26a1158669c7058d5f24898f4
所以set函数的函数选择器为0x60fe47b1

在geth命令行输入如下命令:

eth.sendTransaction({from:eth.accounts[0], to:contractInst.address, value:0, data:"0x60fe47b10000000000000000000000000000000000000000000000000000000000001234"})

from:为调用者的账户。
to:为合约地址。
value:由于此调用的目的不是转账,所以此值为0。
data: 描述了调用那个函数及使用什么参数。格式为:前4个字节为函数选择器。这里是要调用set函数所以为0x60fe47b1,后面紧跟着参数。由于set的参数只有一个uint(uint256),字长为32字节。这里设置的值为0x1234。

调用成功后会显示:

这里写图片描述

挖矿来使函数调用得以执行。在geth命令行输入

miner.start()

执行成功后停止挖矿:

miner.stop()

查询set函数执行结果

eth.getStorageAt(contractInst.address,0)

第一个参数是合约地址,第二个参数是状态变量索引,由于我们的合约目前只有一个状态变量所以这里填0

查询结果如下:

这里写图片描述

返回值为0x1234,说明调用set函数成功!

查询调用结果:

我们也可以通过调用合约中的get函数来查询状态变量storedData。由于get函数为constant所以可以本地同步调用。在geth命令行输入:

contractInst.get.call()

调用结果如下:

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【以太坊傻瓜教程】在私链上发布第一个合约 的相关文章

随机推荐

  • 练习-Java类和对象之包的定义

    第1关 练习 Java类和对象之包的定义 任务描述 编程要求 测试说明 任务描述 本关任务 定义一个电影类和一个电影测试类 在电影测试类中通过对象完成成员变量和成员方法的使用 编程要求 仔细阅读右侧编辑区内给出的代码框架及注释 在 Begi
  • 【Docker】Docker网络

    1 配置容器网络 1 通过实训平台进入到操作系统界面 在 后输入docker run i t d net none ubuntu bin bash命令 启动一个 bin bash容器 示例代码如图1所示 2 在 后输入docker ps a
  • ant-vue中的a-icon使用方法

    Ant Design 图标库 直接引入的使用方式 你直接点击相应的图标会自动将图标名称复制到你的剪切板上
  • Unity3D游戏开发介绍

    Unity3D游戏开发介绍 Unity3D Unity是实时3D互动内容创作和运营平台 包括游戏开发 美术 建筑 汽车设计 影视在内的所有创作者 借助Unity将创意变成现实 Unity平台提供一整套完善的软件解决方案 可用于创作 运营和变
  • CenOS7 下安装wget命令

    1 安装vsfdp yum y install vsftpd 2 关闭防火墙 systemctl stop firewalld service 3 将本机目录下的wget安装文件上传至虚拟机 scp wget 1 14 18 el7 6 1
  • 案例:用户信息列表展示

    1 需求 用户信息的增删改查操作 2 设计 1 技术选型 Servlet JSP MySQL JDBCTempleat Duird BeanUtilS tomcat 2 数据库设计 create database day17 创建数据库 u
  • uva11292 Dragon of Loowater (水题)

    include
  • 电脑怎么在Bios中开启虚拟化

    1 开机按F1进入BIOS Configuration Secuity 2 然后选择Virtulize 或者Intel Virtual Technolody 设置成Enable 3 F10保存 重启
  • String类为什么是不可变的

    String StringBuilder StringBuffer是经常考的东西 其中 String是不可变的 为什么呢 简单解释如下 String类new了一个对象后 我们看到的该对象只是引用 存放了真正内存的地址 并不是真的内存值 如果
  • 500.键盘行 693.交替位二进制数(java实现)

    键盘行 题目 给定一个单词列表 只返回可以使用在键盘同一行的字母打印出来的单词 键盘如下图所示 示例1 输入 Hello Alaska Dad Peace 输出 Alaska Dad 注意 你可以重复使用键盘上同一字符 你可以假设输入的字符
  • 瑞芯微RK3399交叉编译MPP

    上一篇介绍了如何在ubuntu下搭建瑞芯微RK3399的检查编译环境 现在就要开始交叉编译MPP来进行对视频的硬编硬解 这里RK3399用的aarch64架构芯片 上面跑的linux 如果编译android版 需要其他配置 这里主要对lin
  • 101. Symmetric Tree\104. Maximum Depth of Binary Tree\111. Minimum Depth of Binary Tree

    Symmetric Tree 题目描述 代码实现 Maximum Depth of Binary Tree 题目描述 代码实现 Minimum Depth of Binary Tree 题目描述 代码实现 101 Symmetric Tre
  • hcie数通认证考试科目有哪些

    HCIE数通认证考试科目包括网络架构设计和规划 华为路由交换设备的技术和应用 安全和防护 数据中心技术和架构设计以及其他技术和应用1 网络架构设计和规划是HCIE认证考试的重点内容之一 包括网络结构的分层设计 网络拓扑规划 网络性能和可靠性
  • 器件基础知识——电阻

    一 认识电阻 1 耗能能力 电阻对电流有阻碍作用 它自身消耗能量 会将电能转换为热能 为热功率 为流过电阻的电流 为电阻阻值 2 欧姆定律 为加在电阻两端的电压 在电路中为固定值 3 等效模型 理想的电阻器 由纯电阻组成 不受工作频率影响
  • Docker安装教程

    0 安装Docker Docker 分为 CE 和 EE 两大版本 CE 即社区版 免费 支持周期 7 个月 EE 即企业版 强调安全 付费使用 支持周期 24 个月 Docker CE 分为 stable test 和 nightly 三
  • 一个简单的神经网络实例——两层神经网络手写数字识别

    简介 这里是使用神经网络识别手写数字的教程 这个简单的神经网络教程演示了使用numpy从零开始实现一个简单的神经网络 我们定义前向传播和反向传播函数 在训练过程中不断更新权重 完成对数据的拟合 1 准备数据 我们准备了一个简单的训练集 包含
  • 三种素数筛总结——(朴素筛,埃氏筛,线性筛)

    但行好事 莫问前程 题目背景 题目 leetcode 204 计数质数 给定整数 n 返回 所有小于非负整数 n 的质数的数量 对于这类求解素数个数有关的题目 通常采用质数筛算法 本文不计算时间复杂度 只介绍自己对于思路的理解 质数筛 1
  • Backbone 模型 - Backbone.Model

    BackBone模型源码 2013 06 06 11 12 01 分类 JavaScript Backbone 模型 Backbone Model 首先是 Model 模块的源码 Backbone Models 在框架中是基础的数据对象 常
  • 你是否真的适合搞NDK开发?

    最近很多人说 Android越来越不好找工作了 学习NDK开发会不会好点 今天就聊聊这个问题 是否应该选择学NDK 一 哪些场景下要用到NDK开发 跨平台的库 如FFmpeg skip weex 加固 防逆向 签名校验 图片压缩 音视频解码
  • 【以太坊傻瓜教程】在私链上发布第一个合约

    以太坊傻瓜教程 在私链上发布第一个合约 教程简介 本教程将介绍如何编写合约 编译合约以及如何将合约发布到自己的私链上并调用 开发环境 本教程开发环境 操作系统 Windows10 Ethereum客户端 Windows版Geth 可以从这里