在EOS私链上复活PixelMaster的实战
部署私链的目的
区块链中的DApp层出不穷,对于想体验一下又没有真币的程序员来说,编译一个私链并部署智能合约是一个理所当然的想法。对于常见的以太坊和EOS来说,具体操作方法有较大不同。以太坊上的智能合约通常有源码,即使在github上找不到,也可以通过在etherscan.io上找到对应的合约地址,通过其Code功能得到合约源代码,之后可以自己编译源代码然后部署。但是EOS不同,EOS的智能合约编译成WebAssembly(wasm)格式,我尝试过不同的反编译工具,wasmdec/wabt/jeb/idapro wasm plugin等,反编译效果都较差,反编译出的.c文件基本还是汇编码状态,可读性很差。所以放弃反编译源码的想法,直接部署编译好的wasm好了。
这次以曾经火过一段时间的PixelMaster为例,讲一下如何在EOS私链上部署。因为PixelMaster游戏在主链上已经结束,即使这篇文章发出也不会影响该游戏的运营。
准备工作
编译部署EOS私链
网上有很多文章讲如何编译部署EOS私链,这里就不再重复。最好用源码中的tutorials/bios-boot-tutorial/bios-boot-tutorial.py来进行初始化,包括EOS系统帐号,系统合约等。这部分工作完成后,要达到能够自己创建EOS帐户,转帐的程度。
创建PixelMaster所需帐号
PixelMaster运行需要两个EOS帐号:
1pixelmaster:
这个帐号用来部署智能合约,创建过程如下:
cleos create key --to-console
输出如下:
#Private key: 5JqCaFhHwUVeupkNCek1mHYaazPTy1sGa4kLiYm9gMAPao9b1dw
#Public key: EOS64kYDXKQgAbRuCL3XnpJ6xs3rVvTCspb1TnC1k9Zqpdwdtsjzd
将私钥导入到钱包(keosd)中:
cleos --url http://127.0.0.1:8000 --wallet-url http://127.0.0.1:6666 wallet import --private-key 5JqCaFhHwUVeupkNCek1mHYaazPTy1sGa4kLiYm9gMAPao9b1dw
创建EOS帐号:
如果是用bios-boot-tutorial.py来初始化的系统,可以用如下命令创建帐号
cleos --url http://127.0.0.1:8000 --wallet-url http://127.0.0.1:6666 system newaccount --transfer useraaaaaaaa 1pixelmaster EOS64kYDXKQgAbRuCL3XnpJ6xs3rVvTCspb1TnC1k9Zqpdwdtsjzd --stake-net “100.0000 EOS” --stake-cpu “100.0000 EOS” --buy-ram "100.1000 EOS"
pixeldevteam:
这个帐号应该是用来做一些管理工作的备用帐号,按照上面的1pixelmaster的创建方式创建即可。
其他的试玩帐号
如果你还不知道怎么在EOS私链上创建普通的试玩帐号,可以参照上面的创建方式创建其他自定义名字的帐号,之后用如下命令给测试帐号testmanagers转一些EOS:
cleos --url http://127.0.0.1:8000 --wallet-url http://127.0.0.1:6666 push action eosio.token transfer ‘[ “useraaaaaaaa”, “testmanagers”, “10000.0000 EOS”, “m” ]’ -p useraaaaaaaa
获取和部署PixelMaster的智能合约
获取PixelMaster的智能合约
部署EOS智能合约需要.abi文件和.wasm文件。EOS提供了从主网上获取已经部署的智能合约的abi和wasm的功能:
mkdir pixelmaster
cleos --url https://proxy.eosasia.one get code -c pixelmaster/1pixelmaster.wasm -a pixelmaster/1pixelmaster.abi – wasm 1pixelmaster
这样会在pixelmaster目录下生成1pixelmaster.abi和1pixelmaster.wasm两个文件,这就是需要的.abi和.wasm文件。
部署PixelMaster智能合约
现在就可以将从主网上获得的智能合约部署到私链上了:
cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:800 set contract 1pixelmaster ./pixelmaster -p 1pixelmaster
之后有一个初始化步骤要作一下:
cleos --wallet-url http://127.0.0.1:6666 --url http://127.0.0.1:8000 push action 1pixelmaster init ‘[]’ -p 1pixelmaster
至此智能合约在私有链上已经完成了。
部署PixelMaster的网站部分
智能合约是无法玩游戏的,需要有展示的页面来与智能合约交互。
抓取https://pixelmaster.io的页面和资源
这部分比较简单:
- 抓取首页:wget https://pixelmaster.io/
- 根据第1步抓取的index.html中的链接,下载重要的main.xxxxxxxx.chunk.js,其他的css/image/js你可以直接将地址改成https://pixelmaster.io/xxxx,如果你想把他们都下载部署到本地,那就耐心地把这些文件都下载下来并按照目录结构保存好。
- 修改main.xxxxxx.chunk.js,因为这些js都用webpack等作过混淆和压缩,可读性很差,建议你装一个js-beautify,可以对这些js做format,加强可读性,也可以用网上的在线js-formatter.
main.xxxxx.chunk.js里面主要修改如下几个地方:
t.a = {
EOS_CONTRACT_NAME: “1pixelmaster”,
EOS_NETWORK_PROTOCOL: “https”, // —>http
EOS_NETWORK_HOST: “proxy.eosasia.one”, //—>修改为你自己的eos私链地址127.0.0.1
EOS_NETWORK_PORT: Number(“443”), //—>修改为你自己的eos私链的rpc端口上8000
EOS_NETWORK_CHAINID: “aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906”,
//—>修改为你的EOS私链的chainid,如果你用的是bios-boot-tutorial.py初始化的EOS私链,通常为:1c6ae7719a2a3b4ecb19584a30ff510ba1b6ded86e1fd8b8fc22f1179c622a32
另外有一个地方是pixelmaster官方为了防止大家这么搞它,加的一个小手段
if (E(this.o) === “aHR0cHM6Ly9waXhlbG1hc3Rlci5pbw” + this.pp) {
把这句话直接换成:
if (true) {
即可。
4. 剩下就是见招拆招,在浏览器哪些文件或资源找不到,要么修改html/css中的指向,要么从原来pixelmaster.io上下载然后放到正确的位置上。
5. 这些资源放到你自己的http服务器上。
生成data/binary_pixels.txt
PixelMaster把智能合约中记录的绘制点信息定期生成一个binary_pixels.txt文件。大家不要被.txt骗了,这个文件实际上是个二进制文件。这个部分要自己写个程序来做。
获取像素点信息
cleos get table 1pixelmaster “” pixels -l 999999 -L0 -U -1
返回的信息类似于:
{
“rows”: [{
“row”: 0,
“pixels”: [{
“color”: 3856204031,
“priceCounter”: 29,
“owner”: “gmytsobtguge”
},
。。。。。。
,{
“color”: 4294967295,
“priceCounter”: 4,
“owner”: “thegazua2222”
}
]
}
],
“more”: true
}
注意:下面的more如果对应的是true,表示下面还有信息,你需要通过修改-L 的参数值反复取,直到more对应的是false.把取到的信息用程序整合到一个大的json中去。
生成binary_pixels.txt
这个文件实际上就是4096025个点的信息,每个点的信息长度为15个字节,格式为:
0x01+颜色的索引值(1字节)+pixelCounter(1字节)+用户名(12字节)
如果该点没有被画过,15个字节全为0x00
所以该文件大小是固定的4096025*15=15360000
简单的python实现如下,前提是你已经把像素点信息整合到rows.txt中。其他的自行修改。
import json
import sys
def load(filename):
with open(filename) as json_file:
data = json.load(json_file)
return data
def gendatafile(data,filename):
colormap = {0xffffffff:0,0xe4e4e4ff:1,0x888888ff:2,0x222222ff:3,0xa0ba42ff:4,0xe50000ff:5,0xe59500ff:6,0xe5d900ff:7,0x94e044ff:8,0x02be01ff:9,0x00d3ddff:10,0x0083c7ff:11,0x0000eaff:12,0x820080ff:13,0xcf6ee4ff:14,0xffa7d1ff:15}
rows = data[‘rows’]
rowindex = 0
rowid = 40961
if len(rows)>0:
print “len(rows)”,len(rows)
rowid = rows[0][‘row’]
print “rowid:”,rowid
filehandler = open(filename, "wb+")
for i in xrange(40960):
buf = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
if i != rowid:
for j in xrange(25):
filehandler.write(buf)
else:
row = rows[rowindex]
pixelslen = len(row['pixels'])
if pixelslen != 25:
print "rows file invalid"
return
for j in xrange(25):
buf = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
if row['pixels'][j]['owner'] == '':
filehandler.write(buf)
else:
buf[0] = 0x01
if colormap.has_key(row['pixels'][j]['color']):
buf[1] = colormap[row['pixels'][j]['color']]
else:
buf[1] = colormap[0xffffffff]
buf[2] = row['pixels'][j]['priceCounter']
owner = row['pixels'][j]['owner']
buf[3:3+len(owner.encode("utf-8"))] = owner.encode("utf-8")
filehandler.write(buf)
if (rowindex+1 < len(rows)):
rowindex = rowindex + 1
rowid = rows[rowindex]['row']
if name == ‘main’:
length = len(sys.argv)
if length < 3:
print “usage: gendata rowsfile datafile”
exit(1)
data = load(sys.argv[1])
outputfile = sys.argv[2]
gendatafile(data,outputfile)
生成的datafile命名为binary_pixels.txt放到你的PixelMaster的网站的data/目录下
至此合约和网站搭建就基本完成了。
直接用浏览器访问看看是否能显示出来了。
体验
要体验PixelMaster,还差一步:安装scatter。EOS的DApp通常需要安装Scatter。可以安装浏览器插件也可以安装Desktop版本,具体安装方式网上有很多,这里不再细说。
安装完Scatter并将之前创建的测试帐号testmanagers导入到Scatter之后,就可以开始在私链上体验PixelMaster了,这是我的结果。
注意:PixelMaster如果24小时内没有人画像素点,游戏就会结束。