传送门: 柏链项目学院


第二课 智能合约自动化编译

前期内容回顾

之前我们的介绍的是如何通过solc编译智能合约,并且调用智能合约,本节我们继续实践,将智能合约的代码自动化编译以及abi文件生成搞定。

我们需要掌握什么技能呢?

  • go语言调用命令行
  • toml配置文件处理
  • awk工具的使用

go调用命令行

go调用命令行,我们使用exec包

  • LookPath 可以判断一个可执行程序是否存在
  • Command 创建一个命令行
  • cmd.Run() 运行命令行,也可以使用Start()模式,可以去接收管道信息来得到程序返回结果
  • 如果是一个shell脚本,那么可以用/bin/bash来启动

toml配置文件处理

TOML的全称是Tom's Obvious, Minimal Language,因为它的作者是GitHub联合创始人Tom Preston-Werner。TOML 的目标是成为一个极简的配置文件格式。TOML 被设计成可以无歧义地被映射为哈希表,从而被多种语言解析。

toml学习教程

在使用的时候,记得要安装toml第三方包。

go get -u github.com/BurntSushi/toml

之后可以根据我们的需要,来编写配置文件,配置文件的目的仍然是为了让程序运行更灵活,而不应该成为我们的负担!

awk工具使用

awk其实是一个语言,unix平台上处理文本的一种语言,其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。该语言的能力十分强大,可以支持字符串处理,打印等操作,工程中对于文本处理要求比较高的环节多会使用awk进行操作。

awk功能举例:

  1. factory.txt 是一个工厂内目前产品库存情况,如果数量低于75,需要重新下订单,如何处理?
yekaideMacBook-Pro:awk yk$ cat factory.txt
ProdA 70
ProdB 85
ProdC 74

示例如下:

awk '{if ($2 < 75) printf("%s reorder\n",$0);if ($2 >= 75) print $0}' factory.txt
  1. 查看本系统中shell是bash的用户名,并打印
cat /etc/passwd |grep bash|awk -F ":" '{print $1}'
  1. awk处理合约的go文件,将abi信息截取处理存储到文本当中
awk '/const.+ABI = .+/{print substr($4,2,length($4)-2) }' pdbank.go > pdbank.abi

编写自动编译功能

main.go

package main

import (
"fmt"
"os"
) func Usage() {
fmt.Printf("%s 1 -- compiler code\n", os.Args[0])
fmt.Printf("%s 2 -- build test code\n", os.Args[0])
} func main() {
if len(os.Args) < 2 {
Usage()
os.Exit(0)
}
if os.Args[1] == "1" {
CompilerRun()
} else if os.Args[1] == "1" {
//build test code
} else {
Usage()
os.Exit(0)
} }

接下来开始做填空题,也就是如何编译,我们先来实现。先编写扫描目录的代码,获取指定目录的sol文件,然后自动化的形成编译命令,送到命令行执行。

扫描指定目录的sol文件

func CompilerRun() error {
infos, err := ioutil.ReadDir("sol")
if err != nil {
fmt.Println("failed to readdir ", err)
return err
}
for _, v := range infos { //后4位位.sol
strNameRune := []rune(v.Name())
strfix := string(strNameRune[len(strNameRune)-4:])
if strfix == ".sol" && !v.IsDir() {
fmt.Println(v.IsDir(), v.Name(), v.Size(), "ok")
err = CompilerOnece("sol", v.Name(), "contracts")
if err != nil {
fmt.Println("call ompilerOnece err", err)
break
}
}
}
return err
}

编译函数

//编译一个智能合约
func CompilerOnece(solPath, solName, targetPath string) error { //xxx.sol - > xxx.go
goName := strings.Replace(solName, ".sol", ".go", -1) cmd := exec.Command("abigen", "-sol", solPath+"/"+solName, "-pkg", targetPath, "-out", targetPath+"/"+goName)
return cmd.Run()
}

构建abi函数,我们需要先用awk实现一个shell脚本,用来处理go文件的abi信息。

func BuildAbi(goCodeName string) error {
abiName := strings.Replace(goCodeName, ".go", ".abi", -1)
cmd := exec.Command("/bin/bash", "abi.sh", goCodeName, abiName)
err := cmd.Run()
fmt.Println("run BuildAbi ok!!", err)
return nil
}

abi.sh

filename=$1
targetfile=$2
awk '/const.+ABI = .+/{print substr($4,2,length($4)-2) }' $filename > $targetfile

统一调用处理

func ParseRun() {
solfiles, err := ParseDir("sol")
fmt.Println(solfiles, err)
for _, solfile := range solfiles {
fmt.Println(solfile)
codeName, err := Compiler(solfile, "sol", "contracts")
if err != nil {
fmt.Println("failed to complie code", err)
return
}
err = BuildAbi(codeName)
if err != nil {
fmt.Println("failed to build abi", err)
return
}
}
}

这样我们的基础工作完成了,但是代码不够完美,我们需要将部分写死的变量用配置文件来设置,所以再加入toml处理配置文件的部分。

添加config.tomls

[version]
auth = "yekai"
company = "pdj"
buildday = "2019-01-01"
ver = "1.0.0" # 版本 [common]
solidityPath = "sol"
goPath = "contracts"
abiSH = "./abi.sh"

添加config.go

package main

import (
"log" "github.com/BurntSushi/toml"
) type ServerConfig struct {
Version VersionInfo
Common CommonInfo
} type VersionInfo struct {
Auth string
Company string
BuildDay string
Ver string
} type CommonInfo struct {
SolidityPath string //智能合约原路径
GoPath string //输出go代码路径
AbiSH string //处理abi的shell脚本路径
} var ServConf ServerConfig func init() {
getConfig()
} func getConfig() {
var servConf ServerConfig
_, err := toml.DecodeFile("config.toml", &servConf)
if err != nil {
log.Panic("faild to decodefile ", err)
}
ServConf = servConf
//fmt.Println(servConf)
}

接下来替换原来的代码部分

package main

import (
"fmt"
"io/ioutil"
"os/exec"
"strings"
) //编译一个智能合约
func CompilerOnece(solPath, solName, targetPath string) error { //xxx.sol - > xxx.go
goName := strings.Replace(solName, ".sol", ".go", -1) cmd := exec.Command("abigen", "-sol", solPath+"/"+solName, "-pkg", targetPath, "-out", targetPath+"/"+goName)
return cmd.Run()
} //构造abi
func BuildAbi(codePath string) error {
//"contracts/pdbank.go"
//xxx.sol - > xxx.abi
abiName := strings.Replace(codePath, ".sol", ".abi", -1)
goName := strings.Replace(codePath, ".sol", ".go", -1) cmd := exec.Command(ServConf.Common.AbiSH, goName, abiName)
return cmd.Run()
} //扫描目录,获得全部的文件
func CompilerRun() error {
infos, err := ioutil.ReadDir(ServConf.Common.SolidityPath)
if err != nil {
fmt.Println("failed to readdir ", err)
return err
}
for _, v := range infos { //后4位位.sol
strNameRune := []rune(v.Name())
strfix := string(strNameRune[len(strNameRune)-4:])
if strfix == ".sol" && !v.IsDir() {
fmt.Println(v.IsDir(), v.Name(), v.Size(), "ok")
err = CompilerOnece(ServConf.Common.SolidityPath, v.Name(), ServConf.Common.GoPath)
if err != nil {
fmt.Println("call ompilerOnece err", err)
break
}
//创建abi
err = BuildAbi(ServConf.Common.GoPath + "/" + v.Name())
if err != nil {
fmt.Println("call BuildAbi err", err)
break
}
}
}
return err
}

Go语言打造以太坊智能合约测试框架(level2)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. SAP HUM事务代码 HUMAT 之初探

    SAP HUM事务代码 HUMAT 之初探 SAP菜单中,该事务代码在这里: 1)如下的inbound delivery号码, Document flow, 已经完成了PGR, 2)执行HUMAT,进 ...

  2. [转]MS Excel VBO option missing in Blue Prism

    本文转自:https://stackoverflow.com/questions/48706743/ms-excel-vbo-option-missing-in-blue-prism 问: I am ...

  3. Android Glide详细使用教程

    此处我只是做个记录,后边再补充 原文地址:http://www.jufanshare.com/content/35.html 这篇文章写的比较清楚,还附有Demo代码.算是不错的Android Gli ...

  4. 关于IT公司技术委员会职责

    技术委员会的核心职责 组织人才相关 • 制定职级标准 - 能力框架:知识,技能,通用素质 - 职级标准:T2T3T4-P7P8P9- • 职级评审,对齐标准 • 高端招聘,对齐标准 • 校园招聘,对齐 ...

  5. Zabbix系统介绍

    监控概述 硬件监控 IPMI介绍文档:http://www.ibm.com/developerworks/cn/linux/l-ipmi/ 温度:使用ipmi对硬件温度,进行监控 硬盘:使用MegaC ...

  6. Storm入门(九)Storm常见模式之流聚合

    流聚合(stream join)是指将具有共同元组(tuple)字段的数据流(两个或者多个)聚合形成一个新的数据流的过程. 从定义上看,流聚合和SQL中表的聚合(table join)很像,但是二者有 ...

  7. React 基础入门

    React 起源于 Facebook 内部项目,是一个用来构建用户界面的 Javascript 库,相当于MVC架构中的V层框架,与市面上其他框架不同的是,React 把每一个组件当成了一个状态机,组 ...

  8. WPF 通过透明度遮罩和变换制作倒影效果

      倒影效果 代码 <Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http:/ ...

  9. Android进阶之光-第1章-Android新特性-读书笔记

    第 1 章 Android 新特性 1.1 Android 5.0 新特性 1.1.1 Android 5.0 主要新特性 1. 全新的 Material Design 新风格 Material De ...

  10. Chrome浏览器下自动填充的输入框背景

    记录下从张鑫旭老师的微博中看到关于input输入框的属性 1.autocomplete="off" autocomplete 属性规定输入字段是否应该启用自动完成功能 自动完成允许 ...