1.Execute函數執行
調用解析區塊函數
errcode_rpc, trans_list, block_list, new_height, max_height = self.parallel[i]['rpc'].traverse_new_block(self.parallel[i]['filter'],blocks[i], 50)
1.1.traverse_new_block函數裡包括filter_to
對lock_address(鎖定合約位址)進行校驗
def traverse_new_block(self, filter_to, sync_number, count):
filter_to 是經過校驗的 校驗如下
##首先調用合約進行查詢 擷取鍊上資訊
def get_parallel_chain(self,chain_id):
return self.rpc.get_raw_contract(self.inter_reg_addr,self.abi_reg).caller.queryParallelChain(chain_id)
##相應的從資料庫進行查詢 擷取資料庫相應的資訊
chain,gate = self.db.get_chain(list(self.config['parallel-chain'].keys()))
##根據平行鍊ID調用合約查詢對應資料 比對 鎖定lock合約位址 以及 SPV合約位址 是否和資料庫内相同
result = self.get_parallel_chain(id)
if chain[id][4] != result[3]:
logging.info("parallel "+str_id+" lock address not match, db("+chain[id][4]+") query("+result[3]+")")
continue
if chain[id][7] != result[1]:
logging.info("parallel "+str_id+" spv address not match, db("+chain[id][7]+") query("+result[1]+")")
continue
1.2 traverse_new_block内還包括
block = self.get_block(i) 擷取目前區塊資訊,為後面進行交易資訊周遊準備
def get_block(self, number):
return self.web3.eth.getBlock(number)
傳回值 - 區塊對象:
- Number - 區塊号。當這個區塊處于pending将會傳回null。
- hash - 字元串,區塊的哈希串。當這個區塊處于pending将會傳回null。
- parentHash - 字元串,32位元組的父區塊的哈希值。
- nonce - 字元串,8位元組。POW生成的哈希。當這個區塊處于pending将會傳回null。
- sha3Uncles - 字元串,32位元組。叔區塊的哈希值。
- logsBloom - 字元串,區塊日志的布隆過濾器9。當這個區塊處于pending将會傳回null。
- transactionsRoot - 字元串,32位元組,區塊的交易字首樹的根。
- stateRoot - 字元串,32位元組。區塊的最終狀态字首樹的根。
- miner - 字元串,20位元組。這個區塊獲得獎勵的礦工。
- difficulty - BigNumber類型。目前塊的難度,整數。
- totalDifficulty - BigNumber類型。區塊鍊到目前塊的總難度,整數。
- extraData - 字元串。目前塊的extra data字段。
- size - Number。目前這個塊的位元組大小。
- gasLimit - Number,目前區塊允許使用的最大gas。
- gasUsed - 目前區塊累計使用的總的gas。
- timestamp - Number。區塊打包時的unix時間戳。
- transactions - 數組。交易對象。或者是32位元組的交易哈希。
- uncles - 數組。叔哈希的數組。
- 例子
var info = web3.eth.getBlock(3150);
console.log(info);
/*
{
"number": 3,
"hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
"parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88",
"nonce": "0xfb6e1a62d119228b",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee",
"stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb",
"miner": "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty": BigNumber,
"totalDifficulty": BigNumber,
"size": 616,
"extraData": "0x",
"gasLimit": 3141592,
"gasUsed": 21662,
"timestamp": 1429287689,
"transactions": [
"0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b"
],
"uncles": []
}
*/
1.3 def traverse_new_block(self, filter_to, sync_number, count):内 交易處理部分
根據交易hash擷取對應交易詳細資訊
判斷目前區塊内是否和對應filter_to相等 此時比對為lock_address
相等則将對應交易加入transaction_list
此時我們得到 transaction_list為滿足要求的交易 并将其傳回
for j in transaction:
tx = self.get_tx_by_hash(j)
if filter_to != None:
tx_detect = self.convert_common_tx(dict(tx))
if tx_detect['to'] not in filter_to:
continue
tx = dict(tx)
tx["time"] = tx_time
transaction_list.append(tx)
其中 get_tx_by_hash(j)該函數為web3.py提供
def get_tx_by_hash(self, hash):
return self.web3.eth.getTransaction(hash)
傳回值:
一個Promise對象,其解析值為具有給定哈希值的交易對象,該對象具有如下字段:
- hash 32 Bytes - String: 交易的哈希值
- nonce - Number: 交易發送方在此交易之前産生的交易數量
- blockHash 32 Bytes - String: 交易所在塊的哈希值。如果交易處于pending狀态,則該值為null
- blockNumber - Number: 交易所在塊的編号,如果交易處于pending狀态,則該值為null
- transactionIndex - Number: 交易在塊中的索引位置,如果交易處于pending狀态,則該值為null
- from - String: 交易發送方的位址
- to - String: 交易接收方的位址。對于建立合約的交易,該值為null
- value - String: 以wei為機關的轉賬金額
- gasPrice - String: 發送方承諾的gas價格,以wei為機關
- gas - Number: 發送方提供的gas用量
- input - String: 随交易發送的資料
示例代碼:
web3.eth.getTransaction('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b§234')
.then(console.log);
> {
"hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
"nonce": 2,
"blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
"blockNumber": 3,
"transactionIndex": 0,
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"value": '123450000000000000',
"gas": 314159,
"gasPrice": '2000000000000',
"input": "0x57cb2fc4"
}
2. 将處理好的交易清單資訊傳回指派給trans_list
在excute函數當中 調用process_tx函數對經過過濾的交易清單等進行處理
self.process_tx(self.parallel[i]['rpc'],i,trans_list,new_height,max_height)
首先在process_tx函數内 對交易進行解析 判斷是否調用 函數名稱 在methods當中,不是則更新
methods = ['preLock','unLock','lock']
for j in methods:
result, params_list = rpc.parse_tx_input(newtx['to'],newtx['input'],self.parallel[id]['abi_lock'],j)
if result == True:
if 'method' not in params_list:
params_list = {
'method': j,
'params': params_list
}
break
調用函數如下
def parse_tx_input(self, contract_address, input, abi, func):
contract_call = self.web3.eth.contract(address=Web3.toChecksumAddress(contract_address), abi=abi)
result = contract_call.decode_function_input(input)
find = False
for i in result:
if str(i).find("Function " + func) >= 0:
find = True
continue
if find:
return True, i
return False, ""
ps.其中涉及web3.py函數 Contract.decode_function_input(data) 的例子
Contract.decode_function_input(data)
解碼用于調用智能合約函數的交易資料,并将ContractFunction和已解碼的參數作為 dict 傳回。
>>> transaction = w3.eth.getTransaction('0x5798fbc45e3b63832abc4984b0f3574a13545f415dd672cd8540cd71f735db56')
>>> transaction.input
'0x612e45a3000000000000000000000000b656b2a9c3b2416437a811e07466ca712f5a5b5a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000116c6f6e656c792c20736f206c6f6e656c7900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
>>> contract.decode_function_input(transaction.input)
(<Function newProposal(address,uint256,string,bytes,uint256,bool)>,
{'_recipient': '0xB656b2a9c3b2416437A811e07466cA712F5a5b5a',
'_amount': 0,
'_description': b'lonely, so lonely',
'_transactionData': b'',
'_debatingPeriod': 604800,
'_newCurator': True})
之後進行資料格式處理,調用插入更新資料庫操作 并将其type字段賦予1-6代表跨鍊交易進行到了哪步
self.db.update_chain(id,new_height,max_height,commited,newlist)

個人部落格位址 https://www.b2bchain.cn/6369.html
區塊鍊上跨鍊交易 資料成功進行 解析并存儲于資料庫