Web3j实现智能合约

1 获取凭证java

Credentials是咱们钱包的凭证,在咱们交易和建立智能合约的时候都须要用到。linux

1.1 建立新凭证git

file=WalletUtils.generateFullNewWalletFile(pwd,dir);github

返回的file不是全路径,而是该文件的路径名,好比UTC—2017-10-30T12-10-45.516005546Z—5f38056f45091ee992298e53681b0a60c999ff95。web

前面的是建立时间,后面的是帐号标识。编程

1.2 使用旧凭证json

每一个帐号在建立的时候都会生成一个keystore,它是Json格式的。若是要使用旧凭证,首先须要找到咱们的keystore。我这里的服务器搭建在linux服务端,因此这里把keystore拷贝到咱们windows本地。windows

img

而后生成credentials服务器

img

 

2 智能合约maven

2.1 编写智能合约

以太坊编写智能合约有三种语言:

  • Serpent

Serpent是一种相似于Python的语言,可用于开发契约并编译为EVM字节码。它旨在最大限度地简化和清理,将低级语言的许多效率优点与易于使用的编程风格相结合,同时为合同编程添加特定领域特定功能。蛇是使用LLL编译的。

  • Solidity

这是一种相似于JavaScript的语言,它容许你开发合同并编译为EVM字节码。它目前是以太坊的旗舰语言,也是最受欢迎的。

咱们这里编写一份Hello World

contract HelloWorld

{

address creator;

string greeting;

function HelloWorld(string _greeting) public

{

creator = msg.sender;

greeting = _greeting;

}

function greet() constant returns (string)

{

return greeting;

}

function setGreeting(string _newgreeting)

{

greeting = _newgreeting;

}

/

Standard kill() function to recover funds

/

function kill()

{

if (msg.sender == creator)

suicide(creator); // kills this contract and sends remaining funds back to creator

}

}

  • LLL

Lisp Like Language(LLL)是一种相似于Assembly的低级语言,它意味着很是简单和简约,基本上就是直接在EVM中进行编码的一个小包装。

还有一种已经被弃用了,这里咱们选用官方标准的Solidity语言编写。

2.2 编译智能合约

这里使用Solidity的在线编译器https://ethereum.github.io/browser-solidity/

把咱们上面编写好的智能合约代码贴进去。

img

而后点击Details

img

这里的name就是智能合约的名称,ABI文件会暴露合同的全部构造参数,咱们须要用ABI文件生成java类。WEB3是生成好的js文件,能够配合web3.js直接调用。

2.3 Solidity类转换成java类

若是想要避免使用智能合约的底层实现细节,web3j提供了Solidity 智能合约包装,使您能够经过生成的包装对象直接与全部智能合约的方法进行交互。

这里咱们把ABI文件复制一下,而后粘贴到本地做为.json文件,名字最好和类名同样,好比我这里叫HelloWorld.json。这里有一个大坑,就是编译器生成的JSON文件格式不对,没有合约名字,若是咱们执行转换会报错。

img

这里咱们打开json文件手动编译一下

img

web3j支持从Solidity ABI文件在Java中自动生成智能合约函数包装器。

web3j 命令行工具附带一个用于生成智能合同函数包装器的命令行工具:

先去官方下载一个命令行工具

https://github.com/web3j/web3j/releases/tag/v3.2.0

img

下载.zip文件解压到本地。

找到web3.bat文件执行 $ web3j truffle generate [—javaTypes|—solidityTypes] /path/to/.json -o /path/to/src/main/java -p com.your.organisation.name

上面这个是官方的格式不太通俗易懂,我给你们翻译一下:

Web3j truffle generate json文件地址 -o 生成的文件目录 -p 生成的文件包名。这里要注意 -o 和-p也要带上。

若是web3.bat文件点不开,就直接使用cmd命令执行,在执行的时候带上web3j的全路径就好了,执行完成以后控制条会显示:

img

或者也能够经过Java类进行调整,添加web3j的相关依赖,而后使用maven指定运行。

img

这里把生成好的java类拷贝到咱们的代码里面。

2.4 发布智能合约

合约生效时间

private static final String BINARY =null;

这个BINARY表明智能合约的生效时间,生成的类里面默认是NULL. 若是不修改这个时间执行智能合约默认是失效的,因此这里咱们修改一下为官方指定的二进制代码。

在编译器里面也能够看到咱们生成的合约二进制文件。

img

就是这一行,咱们拷贝过来就行了。

部署智能合约

//部署智能合约

HelloWorld contract=deploy(admin, credentials,ManagedTransaction.GAS_PRICE, Contract.GAS_LIMIT,“Hello,World”).send();

部署合约须要消耗Gas.这里说一下我对以太坊Gas的理解:

交易的过程通常须要支付必定量的手续费(固然也能够选择不支付)。矿工会优先打包交易手续费高的交易,若是没有支付交易手续费,你的交易可能要等好久才会被打包。建立一笔交易的时候不须要显式的指明支付多少交易手续费,它是根据你的 UTXO额 – 交易额 – 找零 来计算的。举个栗子,A有一个10btc的UTXO(未花费的交易输出)的支配权,它给B帐户转1BTC,那么在建立交易的时候,须要指明交易额1btc,和找零8.995,那么(10-8.995-1 = 0.005)就是这笔交易的手续费,会奖励给打包包含这笔交易的区块的矿工,若是没有设置找零那么多余的9btc都会被看成交易手续费奖励给矿工,虽然你的交易会很快的被打包,可是这可能不是你想要的。

  • 这样能够鼓励更加高效的合约代码,减小没必要要的计算,避免系统遭受攻击,毕竟攻击者要为他们消耗的资源付出必定的代价,包括带宽,CPU,和存储。 gasPrice 是由交易的发起者来设置的,可是矿工能够选择先打包那些gas价格高的交易,gas价格低的可能要等好久或者不会被打包。
  • 例如一笔交易:{ from:web3.eth.accounts[0], data:tokenCompiled.token.code, gas: 1000000 }, gas参数设置这个交易最多能使用多少gas。交易里面还能够再加一个参数gasPrice,gasPrice能够本身设置, geth会默认设置一个大多数矿工能够接受的 gasPrice, 0.05e12 wei,能够调eth.gasPrice来查看当前的gasPrice.
  • 矿工在启动geth的时候能够设置两个参数—ask 和 —bid , —ask是设置一个最低的gas价格,低于这个价格的交易会被忽略,默认值是500000000000,—bid 设置gas价格竞价,默认值是 500000000000。

合约地址

//获取合约地址

String contractAddress = contract.getContractAddress();

合约发布成功以后会在ETH客户端生成一个合约地址,咱们在之后调用的时候都须要用到。

验证合同是否有效

使用这种方法,您可能须要肯定已经加载的合同地址是您指望的智能合约。为此,您可使用isValid智能合约方法,只有在合约地址已部署字节码与智能合约包装中的字节码匹配时才会返回true.

System.out.println(contract.isValid());

若是返回false,多是由于智能合约代码生成的有问题,也有多是合同生效时间没有设置。

加载智能合约

若是咱们想使用已经部署过的智能合约,这个时候咱们就须要加载智能合约了,

在加载智能合约的时候你须要拥有该智能合约的地址。

HelloWorld contract =HelloWorld.load(contractAddress,admin,credentials, GAS_PRICE, GAS_LIMIT);

调用智能合约

String value=contract.greet().send();

log.info(value);

调用咱们编译好的get方法,会在控制台打印Hello World。表明咱们此次合约部署调用成功。

销毁智能合约

contract.kill();

销毁后的智能合约没法调用,可是能够查询到。

 

原文连接:http://wangxiaoming.com/blog/2018/01/22/HPB-41-ETH-3j-Smart/

相关文章
相关标签/搜索