目錄
安裝 Go
Golang官方下載,選中對應版本,複製地址。
wget https://dl.google.com/go/go1.10.1.linux-amd64.tar.gz
tar -zxvf go1.10.1.linux-amd64.tar.gz
cd go
# 獲得go安裝地址 /mnt/ont-dev/ontology/go
pwd
mkdir -p /mnt/ont-dev/GoPath
vim /etc/profile
# Shift + G跳至末尾行,添加環境變量
# 將GOROOT的值改成go安裝地址
export GOROOT=/mnt/ont-dev/go
export GOPATH=/mnt/ont-dev/GoPath
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 最後生效以下環境變量
source /etc/profile .
# OK,查看一下go版本,驗證是否安裝成功
go version
安裝第三方包管理工具glide
yum intall glide
yum intall git
源碼編譯部署ONT本體測試鏈
將源碼拉取到$GOPATH/src/github.com/ontio/ontology目錄
mkdir -p $GOPATH/src/github.com/ontio
git clone https://github.com/ontio/ontology.git
cd $GOPATH/src/github.com/ontio/ontology
拉取依賴包,此操作會消耗很長時間,但多數依賴都是從GitHub上拉取,並且有一部分依賴已失效(有些需要翻牆),需要手動從GitHub上一個個的下載,然後存放在指定位置。接下來我們拉取依賴:
glide install
通過make編譯源碼:
make all
!!!make all 會有報錯,缺少依賴!!!
這時候可能會有小夥伴奇怪,爲什麼呢?原因是因爲長城防火牆,導致了在glide install拉取依賴時網絡不通暢,拉取失敗了,在這裏提供兩種解決方案:
一、將上面紅色標記處的依賴代碼下載下來(完整的項目),讓在指定位置,例如:缺少<github.com/ethereum/go-ethereum/common/fdlimit >,則訪問https://github.com/ethereum/go-ethereum/common/fdlimit 發現是404,怎麼辦呢?
不用着急,我們找到go-ethereum工程,將源碼下載下來。然後上傳至服務器,並解壓縮到GoPath對應的ethereum目錄下面(目錄不存在則手動創建),我們再次make all將不會再提示找不到fdlimit依賴。
缺少的其它依賴按照上述方法操作即可!爲防止小夥伴走丟,附上兩張圖:
二、作者提供當前版本(ontology v1.8.1)完整依賴壓縮包GoPath.zip,將GoPath目錄覆蓋即可。將gopath.zip文件上傳至/mnt/ont-dev:
unzip gopath.zip
繼續嘗試編譯源碼,make all:
如果出現如下錯誤信息,說明未將源碼放在$GoPath/src/github.com/ontio目錄下.
# command-line-arguments
./main.go:67:13: cannot use startOntology (type func(*"github.com/urfave/cli".Context)) as type "github.com/urfave/cli".ActionFunc in assignment
./main.go:71:6: cannot use cmd.AccountCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:72:6: cannot use cmd.InfoCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:73:6: cannot use cmd.AssetCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:74:6: cannot use cmd.ContractCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:75:6: cannot use cmd.ImportCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:76:6: cannot use cmd.ExportCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:77:6: cannot use cmd.TxCommond (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:78:6: cannot use cmd.SigTxCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:79:6: cannot use cmd.MultiSigAddrCommand (type "github.com/ontio/ontology/vendor/github.com/urfave/cli".Command) as type "github.com/urfave/cli".Command in array or slice literal
./main.go:79:6: too many errors
make: *** [ontology] Error 2
編譯完成會在源碼根目錄下生產兩個文件:
ontology: 節點程序/以命令行方式提供的節點控制程序
tools/sigsvr: (可選)簽名服務 - sigsvr是一個簽名服務的server以滿足一些特殊的需求。詳細的文檔可以在這裏參考。
可以看到這兩個文件說明已經完成測試鏈的部署!
Docker部署ONT本體測試鏈
與源碼編譯一致,源碼必須能通過make編譯否則將無法打鏡像,所以在打鏡像前需要先make一下。將源碼拉取到$GOPATH/src/github.com/ontio/ontology目錄:
mkdir -p $GOPATH/src/github.com/ontio
git clone https://github.com/ontio/ontology.git
cd $GOPATH/src/github.com/ontio/ontology
拉取依賴包,此操作會消耗很長時間,但多數依賴都是從GitHub上拉取,並且有一部分依賴已失效,需要手動從GitHub上一個個的下載,然後存放在指定位置。
glide install
make all
如出現異常,請參考源碼編譯解決方案!編譯完成會在源碼根目錄下生產兩個文件:
make docker
可以看到,鏡像已經生成,接下來我們讓它跑起來:
docker run -ti ontio/ontology --networkid 2
-d後臺運行,這裏我們採用更直觀的交互式運行,方便查看測試鏈區塊同步狀況,當然你也可以使用自動化交互後臺啓動。
可以開到啓動後自動開始同步測試鏈區塊。
重開一個客戶端,查看正在運行的容器列表
docker ps
接下來咱們需要進入鏡像內部,以及找到節點控制程序:
docker exec -it adoring_chatelet bash
到這裏Docker安裝部分已經全部結束!接下來我們我們需要創建測試鏈錢包,接入測試網絡。
創建ONT錢包
如果是編譯部署,我們創建一個目錄方便管理。
Cd /mnt/ont-dev/GoPath/src/github.com/ontio/ontology
#創建一個目錄用來存放,節點客戶端程序以及錢包文件
mkdir /mnt/ont-dev/ont
# copy一份節點客戶端程序
cp ontology /mnt/ont-dev/ont
Cd /mnt/ont-dev/ont
接下來我們開始創建錢包,按照默認設置創建一個錢包賬戶,默認配置如下:
簽名算法 |
ecdsa |
曲線 |
P-256 |
簽名方案 |
SHA256withECDSA |
./ontology account add --default
輸入設置錢包文件密碼123456,密碼丟失,錢包文件將無法解密,也就意味着你的私鑰丟失了:
Address:AWFjLjTSmsKUTZJp7YxKpq5pXagyoJjSsn Public key:02af0752af9d669a29cdddc6c625b8e66b0c81eacf37d7d47653bdd3dc7eaac786 Signature scheme:SHA256withECDSA Create account successfully. |
先不要急着查看地址餘額,啓動測試網絡之後才能查看。
節點部署
本地測試網絡部署節點
首先需要創建一個默認錢包(如果你已經創建了默認錢包請忽略此步):
./ontology account add --default
如下爲我生成的賬戶錢包地址:
Address:AMMWWMW77HTB1VyW6jdGu3utWxd78DZetA Public key:0222415b7caf12cbe2efe19eaa4a7861e1b8c24decaae4e0a72764eaf267f67f83 Signature scheme:SHA256withECDSA Create account successfully. |
$ ./ontology --testmode --enable-consensus
#--testmode 本地測試網部署
#--enable-consensus 開啓節點共識,不開啓將不會產生區塊,所以必須開啓,這點很重要!!
#--disable-rpc 關閉rpc服務
#--disable-event-log是關閉日誌服務
#--config 設置創世區塊配置文件
#--account 設置錢包賬戶
#--gasprice 燃油價格
#--gaslimit 所能支付的最大燃油費,如果單筆交易超過了這個值,將會中斷交易,而已經使用的Gas將不會退還。
#注:通過--help可以查看所有命令的幫助信息哦~
查看一下地址餘額:
注:如果你看到的餘額爲0,請在啓動本地測試網絡之後再進行查看。
自動化交互後臺運行
1、安裝expec
yum install tcl-devel
yum install expect
#注:expect是一個自動化交互套件,主要應用於執行命令和程序時,系統以交互形式要求輸入指定字符串,實現交互通信。
2、創建start.sh文件
cd /mnt/ont-dev/ont
vim start.sh
輸入以下內容:
#!/usr/bin/expect -f
# 上一句,指定通過expect來運行此腳本
# 通過spawn 啓動
spawn ./ontology --testmode --enable-consensus
# 指定當出現"Password:"關鍵字的時候幫助我們完成交互
expect "Password:"
# send當出現關鍵字的時候輸入一下內容 “\n”==回車
send -- "123456\n"
# interact保持交互狀態,沒有interact將會直接退出
interact
3、啓動節點,指定控制檯日誌輸出到ont.log文件
./start.sh > ont.log 2>&1 &
4、查看一下端口,檢查是否啓動成功,可以看到如下三個端口表示啓動成功:
netstat -ntpl
查看一下控制檯日誌:
我們發現,ong.log只保存了部分日誌,這是因爲存在兩層交互的原因,ont.log只能收錄到start.sh文件的輸出,而start.sh中與expect交互部分的輸出是無法收錄的,簡單的說就是已經誇應用了,如果想要查看詳細的日誌,可以去ONT日誌Log文件夾中查看:
cd /mnt/ont-dev/ont/Log
查看最近日期的日誌文件:
tail -200f 2019-11-27_10.40.32_LOG.log
官方Polaris測試網部署節點
./ontology --networkid 2
詳細參數同上。由於測試網絡節點太多,同步時間太長,開發不推薦部署使用,區塊高度比主網高出48w左右。
測試網絡部署後創建的賬戶餘額爲0,所以需要在官方申請測試幣。
主網節點部署
官方推薦記賬節點配置:
./ontology --enable-consensus --disable-rpc --disable-event-log
Java 錢包開發實戰篇
ONT爲實際數量爲整數,ONG爲實際數量×10^9,精度爲9,每筆交易收取0.01ONG。
ONT 和 ONG 的地址爲大小寫敏感,請務必注意。
對於在主網轉賬,請將 gaslimit 設爲 20000,gasprice 設爲500
創建ONT錢包
如果是編譯部署,我們創建一個目錄方便管理。
Cd /mnt/ont-dev/GoPath/src/github.com/ontio/ontology
//創建一個目錄用來存放,節點客戶端程序以及錢包文件 mkdir /mnt/ont-dev/ont
// copy一份節點客戶端程序 cp ontology /mnt/ont-dev/ont
Cd /mnt/ont-dev/ont |
接下來我們開始創建錢包:
// 按照默認設置創建一個錢包賬戶,默認配置如下: //簽名算法:ecdsa //曲線:P-256 //簽名方案:SHA256withECDSA
./ontology account add --default
// 輸入設置錢包文件密碼123456,密碼丟失,錢包文件將無法解密,也就意味着你的私鑰丟失了
Address:AWFjLjTSmsKUTZJp7YxKpq5pXagyoJjSsn Public key:02af0752af9d669a29cdddc6c625b8e66b0c81eacf37d7d47653bdd3dc7eaac786 Signature scheme:SHA256withECDSA Create account successfully. |
查看ONT錢包列表
./ontology account list
|
導入錢包
$ ./ontology account import -s walletfile.dat |
交易轉賬
我創建了兩個地址: AMMWWMW77HTB1VyW6jdGu3utWxd78DZetA,ARMYgzbgo6rgWnToM7PPbQ5AbfiVv1aomQ //查看餘額 $ ./ontology asset balance 地址
可以看到他們的餘額分別是: 接下來我們進行轉賬:
$ ./ontology asset transfer --from=AMMWWMW77HTB1VyW6jdGu3utWxd78DZetA --to=ARMYgzbgo6rgWnToM7PPbQ5AbfiVv1aomQ --amount=10 --asset=ont
$ ./ontology asset transfer --from=1 --to=2 --amount=10000 --asset=ont
輸入密碼轉賬:
OK,轉賬成功了,它提示我們通過info status可以查看事務狀態,那我們查看一下: State 1表示交易成功,GasConsumed表示收取的ONG燃油,由於本地測試鏈默認爲0,Notify輸出日誌。詳細請參考:https://github.com/ontio/ontology/blob/sharding/docs/specifications/cli_user_guide_CN.md#42-%E6%9F%A5%E8%AF%A2%E4%BA%A4%E6%98%93%E4%BF%A1%E6%81%AF |
cli 使用說明:
https://github.com/ontio/ontology/blob/sharding/docs/specifications/cli_user_guide_CN.md
申請測試幣
我們去官方申請測試幣:https://developer.ont.io/applyOng ./ontology asset balance
|
查看未解綁的ONG餘額(空投)
./ontology asset unboundong <address|index|label> |
提取未解綁的ONG餘額
./ontology asset withdrawong <address|index|label> |
測試:
/*
// OEP-5 Or OEP-8 遊戲相關協議,複雜程度更高,目前在用只有ONT自己的兩個遊戲實驗項目。
|
創建合約
ERC-20、ERC-223、ERC-721(NEP-4、NEP-5、NEP-8)的區別
ERC-20與NEP-4對應,都是基礎token標準,ERC-223與NEP-5對應都是升級token標準(允許合約-合約交易) ,ERC-721與NEP-8對應每份token都是唯一的,是一種物權所有權憑證標準,在遊戲中應用更爲廣泛。
客戶端配置
import com.comex.exceotion.ChainClientException;
import com.github.ontio.OntSdk;
import com.github.ontio.sdk.exception.SDKException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @program: comex-wallet
* @description: ONT錢包客戶端配置
* @author: Mr.LMing.X
* @create: 2019-11-22 18:34
**/
@Slf4j
@Configuration
public class OntClientConfig {
// 默認rpcUrl = http://182.61.12.9:20336
@Value("${wallet.rpcUrl}")
private String rpcUrl;
@Bean
public OntSdk getOntSdk() {
OntSdk ontSdk;
try {
ontSdk = OntSdk.getInstance();
ontSdk.setRpc(rpcUrl);
ontSdk.setRestful("http://192.168.1.223:20334");
ontSdk.setDefaultConnect(ontSdk.getRpc());
// ontSdk.openWalletFile("wallet.dat");
} catch (SDKException e) {
log.error("獲取ONT錢包客戶端時發生異常 SDKException error:{}", e);
throw new ChainClientException(e);
} catch (Exception e) {
log.error("獲取ONT錢包客戶端時發生異常 Exception error:{}", e);
throw new ChainClientException(e);
}
return ontSdk;
}
}
通過SDK創建錢包
注意保存私鑰!!!
public void createAccount() throws Exception {
com.github.ontio.account.Account acct = new com.github.ontio.account.Account(ontSdk.defaultSignScheme);
//私鑰
System.out.println(Helper.toHexString(acct.serializePrivateKey()));
//公鑰
System.out.println(Helper.toHexString(acct.serializePublicKey()));
//base58地址
System.out.println(acct.getAddressU160().toBase58());
com.github.ontio.sdk.wallet.Account accountFromPriKey = ontSdk.getWalletMgr().createAccountFromPriKey("123456", Helper.toHexString(acct.serializePrivateKey()));
System.out.println(accountFromPriKey.key);
System.out.println(accountFromPriKey.isDefault);
ontSdk.getWalletMgr().writeWallet();
System.out.println("init size: " + ontSdk.getWalletMgr().getWallet().getAccounts().size() + " " + ontSdk.getWalletMgr().getWalletFile().getAccounts().size());
System.out.println(ontSdk.getWalletMgr().getWallet().toString());
System.out.println(ontSdk.getWalletMgr().getWalletFile().toString());
}
導出錢包文件
$ ./ontology account export ./export_wallet.dat
|
在線IDE編寫OEP-4合約
在線IDE:https://smartx.ont.io/
創建一個Python的OEP-4協議的合約:
OntCversion = '2.0.0'
"""
An Example of OEP-4
"""
from ontology.interop.System.Storage import GetContext, Get, Put, Delete
from ontology.interop.System.Runtime import Notify, CheckWitness
from ontology.interop.System.Action import RegisterAction
from ontology.builtins import concat
from ontology.interop.Ontology.Runtime import Base58ToAddress
TransferEvent = RegisterAction("transfer", "from", "to", "amount")
ApprovalEvent = RegisterAction("approval", "owner", "spender", "amount")
ctx = GetContext()
NAME = '冥幣' // 代幣名稱
SYMBOL = 'MingB' // 幣種名稱
DECIMALS = 8 // 精度
FACTOR = 100000000 //最小單位參考精度
OWNER = Base58ToAddress("AQf4Mzu1YJrhz9f3aRkkwSm9n3qhXGSh4p") // 合約所有者,默認合約的所有者爲你所上傳的錢包文件第一個賬戶,可以改
# OWNER = bytearray(b'\x61\x6f\x2a\x4a\x38\x39\x6f\xf2\x03\xea\x01\xe6\xc0\x70\xae\x42\x1b\xb8\xce\x2d')
TOTAL_AMOUNT = 1000000000 // 代幣發行總量
// 下面則是一些默認的校驗規則的定義了
BALANCE_PREFIX = bytearray(b'\x01')
APPROVE_PREFIX = b'\x02'
SUPPLY_KEY = 'TotalSupply'
// 一切調用的入口Main
def Main(operation, args):
//...省略內容,參考默認內容
// init 初始化方法,在創建完成之後需要進行調用,初始化發行量,所有者等信息
def init()
//...省略內容,參考默認內容
Name(),symbol(),decimals(),totalSupply()分別代表獲取幣種名稱、幣種、精度、總量
其他方法我們用到了在進行詳細介紹,讀者也可參考NEP-4協議說明:
編譯合約
我們通過右側工具欄選擇2.0版本,編譯,編譯成功後悔生成一串16進制的AVM字節碼,導出成.avm文件,注意avm中如果有雙引號請刪除!
部署合約
客戶端方式
./ontology contract deploy --code Ming.avm --name Ming --version 2.0.0 --author Ming --email [email protected] --desc 命幣 --gaslimit 30000000 --needstore:指定智能合約需要使用持久化的合約存儲(默認不使用)。 --code:指定存儲智能合約 AVM 字節碼文件的路徑。 --name:指定智能合約的名稱。 --version:指定智能合約的版本號。 --author:指定智能合約的作者信息。 --email:指定智能合約的聯繫人電子郵件。 --desc:指定智能合約的描述信息。 --prepare, -p:指定智能合約的預部署。 響應: Deploy contract: Contract Address:8b1c36e5b1c49d14fc46e0f27107f1c4575b4ef3 TxHash:f0bd7cdfc0ac62b549364a6a78d236ab6fdc3877e751dbea7150bdea82ec742b |
Java-SDK方式
InputStream is = new FileInputStream("/Users/sss/dev/ontologytest/IdContract/mingb.avm"); byte[] bys = new byte[is.available()]; is.read(bys); is.close(); code = Helper.toHexString(bys); ontSdk.setCodeAddress(Address.AddressFromVmCode(code).toHexString());
//部署合約, Transaction tx = ontSdk.vm().makeDeployCodeTransaction(code, true, "MingB","v2.0", "Lming.X", "[email protected]","desp", account.getAddressU160().toBase58(),ontSdk.DEFAULT_DEPLOY_GAS_LIMIT,500);
String txHex = Helper.toHexString(tx.toArray()); ontSdk.getConnect().sendRawTransaction(txHex); //等待出塊Thread.sleep(6000); DeployCodeTransaction t = (DeployCodeTransaction) ontSdk.getConnect().getTransaction(txHex); |
合約初始化
初始化我們通過sdk完成。
// 合約初始化 // 參數:到賬賬戶,支付賬戶,gaslimit,gasprice |
合約轉賬
數字貨幣和代幣(Token)的區別
數字貨幣一般指一個區塊鏈項目的平臺代幣,比如以太坊上的以太幣,元界上的 ETP 都是基礎代幣。
而 Token 往往代表了一種資產,這些資產在已經存在的其他區塊鏈之上運行,資產還可以像商品一樣交易,例如消費積分、遊戲虛擬資產。Token 離具體的區塊鏈應用也會更近,因爲區塊鏈應用的項目方通常也是 Token 的發行方。
本體/以太坊賬戶模型
不同於UTXO賬戶模型,ONT借鑑了以太坊的賬戶模型。
第一類叫做合約賬戶 CA(Contracts Accounts),第二類叫做外部賬戶 EOA(Externally Owned Accounts)
簡單理解就是:
CA 是智能合約代碼用的賬戶,EOA 是人用的賬戶;所以 CA 可以存儲並執行智能合約代碼,它的智能被 EOA 激活,它也不保存和存儲私鑰,合約賬戶可以調用其他合約。
EOA 則是人們直接控制的賬戶,可以存儲以太幣,可以發送交易到合約賬戶,觸發既定的邏輯。EOA 賬戶由公鑰標識,由對應的私鑰控制。
當合約賬戶被調用時,存儲其中的智能合約可以在礦工處的虛擬機中自動執行,並消耗 Gas,如果 Gas 不足則會觸發“Out of Gas”異常,被終止執行。
無論是 CA 還是 EOA,在以太坊內部都被看做狀態對象(state objects),意思就是說這些賬戶都有自己的狀態,EOA 具有以太幣餘額的狀態,而 CA 除了餘額,還多了合約存儲狀態。
ONT轉賬(EOA-> EOA)
Ont爲整數,轉賬數量爲實際數量。
// 地址:Aco8xpeQUaxsBN6BfEM4ykfkmaiGokMoyo
// 6cbbc353882d53403d1410b16a3908cd0823286539b05f6206c0a9e5067b4b6a |
ONG轉賬(EOA-> EOA)
Ong精度9,轉賬時進行精度轉換。
Long amount = new BigDecimal(30).multiply(BigDecimal.TEN.pow(9)).longValueExact();
|
OEP-4合約賬戶向普通賬戶轉賬Token(CA -> EOA)
// 查詢精度
|
查看一下交易狀態:
OEP-4外部賬戶向合約賬戶轉賬(EOA -> CA)
這裏解釋一下,如果一個外部賬戶向合約賬戶轉賬的是數字資產(ont/ong)則與不同轉賬並無區別。
如果是轉賬Token,那麼用說 代幣所有人賬戶 向 合約所有人賬戶 轉賬更加貼切,本質上合約所有人也是一個代幣(Token)所有人。
System.out.println("\n " + oep4ContractAcct.getAddressU160().toBase58() + ": " + ontSdk.neovm().oep4().queryBalanceOf(caAcct3.getAddressU160().toBase58())); |
代幣賬戶 -> 代幣賬戶 Token(EOA -> EOA)
同上。
合約同時多筆轉賬
// com.github.ontio.core.asset.State; // 合約多筆轉賬
|
查詢區塊所在高度
SDK:ontSdk.getConnect().getBlockHeightByTxHash("txhash") HTTP:http://182.61.12.9:20334//api/v1/block/height/txhash/ Cli:./ontology info tx <txhash> |