如何使用以太坊和蛇存储“复杂”数据结构作为持久数据结构
我的工作涉及
Smart Contract dev.使用
(py)ethereum和
serpent,
阅读“A Programmer’s Guide to Ethereum and Serpent”时,我在第5.9点看到:
和:
代码示例: #!/usr/bin/env python # -*- coding: UTF-8 -*- import serpent from ethereum import tester,utils,abi serpent_code = ''' data mystorage[] def test_data_storage(key,value): if not self.mystorage[key]: self.mystorage[key]=value return(1) else: return(0) def get_value_mystorage(key): if not self.mystorage[key]: return(0) else: return(self.mystorage[key]) def test_self_storage(key,value): if not self.storage[key]: self.storage[key]=value return(1) else: return(0) def get_value_self_storage(key): if not self.storage[key]: return(0) else: return(self.storage[key]) ''' s = tester.state() c = s.abi_contract(serpent_code) #example with self storage c.test_self_storage("keyA",1) print c.get_value_self_storage("keyA") #store and access data works in self.storage! #example with mystorage c.test_data_storage("keyB",2) print c.get_value_mystorage("keyB") #store and access data works in data as persistant data storage! #fail example with complex data my_complex_data={"keyA":1,"keyB":2,"keyC":[1,2,3],"keyD":{"a":1,"b":2}} c.test_data_storage("keyComplex",my_complex_data) #don't store anything because error: # ethereum.abi.ValueOutOfBounds: {'keyC': [1,'keyB': 2,'keyA': 1,'keyD': {'a': 1,'b': 2}} 我的问题是:什么是最好的方法以及如何存储复杂的数据(参见代码中的my_complex_data变量),就像包含其他字典的字典一样. (或数组作为键值)作为持久数据结构? 有人知道是否可能以及如何将任何类结构存储为持久数据结构? 解决方法
重要提示:请注意,根据
this Vitalik Tweet,Serpent现在是一个“过时的技术”.
Serpent README已更新为:
如果您想从Python编写以太坊合约以发布生产产品,请开始考虑迁移到Solidity或Vyper(这仍然是“新的实验性编程语言”) 关于我的问题,我最终找到了一个(棘手/肮脏)解决方案,它包括在将复杂数据推送到持久数据存储之前对其进行编码,然后在从存储中检索数据后进行解码. 请参阅下面的更新代码: #!/usr/bin/env python # -*- coding: UTF-8 -*- import serpent import json,math from ethereum import tester,value): if not self.storage[key]: self.storage[key]=value return(1) else: return(0) def rebuild_complex_data_storage(key): if not self.storage[key]: return(0) def get_value_self_storage(key): if not self.storage[key]: return(0) else: return(self.storage[key]) def put_complex_data_storage(key,value=""): self.storage[key]=value def get_complex_data_storage(key): return(self.storage[key]) ''' s = tester.state() c = s.abi_contract(serpent_code) #example with self storage c.test_self_storage("keyA",2) print c.get_value_mystorage("keyB") #store and access data works in data as persistant data storage! start_block="99699" def block_chain_encode(c,key,my_complex_data): #ENCODE PART global start_block print "n","*","ENCODE","*" #fail example with complex data my_complex_data_json_format=unicode(json.dumps(my_complex_data)) int_str=start_block for each in my_complex_data_json_format: int_str=int_str+ str(ord(each)).zfill(4) int_str=int_str+start_block print int_str #toHex = lambda x:"".join([hex(ord(c))[2:].zfill(2) for c in x]) print "need to declare 32 bit words",math.ceil(len(int_str)/32.),"times" #max 32 char for each key max_size=int(math.ceil(len(int_str)/32.)) for i in range(0,max_size): block_content=int_str[i*32:(i+1)*32] print "block",i," content",block_content if i==0: c.test_data_storage("keyComplex_len",max_size) key="keyComplex_"+str(i).zfill(3) res=c.test_data_storage(key,int(block_content)) #store block part in block chain print " - substorage","",#print "data storage part is done !" return 1 def block_chain_decode(c,key): #DECODE PART global start_block print "n","DECODE","*" int_str="" lenght= c.get_value_mystorage("keyComplex_len") #get lenght to know how many block we need to get for all data from block chain for i in range(0,lenght): key="keyComplex_"+str(i).zfill(3) print key,c.get_value_mystorage(key) int_str=int_str+str(c.get_value_mystorage(key)) content_="" sp_int_str= int_str.split(start_block) if len(sp_int_str)==3: if sp_int_str[-1]==sp_int_str[0] and sp_int_str[0]=="": print "ok" content_=sp_int_str[1] js_str="" if content_!="": for i in range(0,int(len(content_)/4.)): js_str+=chr(int(content_[i*4:(i+1)*4])) #recover char from asci code my_complex_data=json.loads(js_str) return my_complex_data #define complex data my_complex_data={"keyA":1,"b":2}} print "Initial complex data",my_complex_data #encode and push to block chain block_chain_encode(c,"keyComplex",my_complex_data) #get complex variable from block chain my_complex_data_back = block_chain_decode(c,"keyComplex") #acces data print my_complex_data_back["keyD"]["a"]+my_complex_data_back["keyD"]["b"] print "Extracted complex data from blockchain",my_complex_data print "Integrity test pass:",my_complex_data_back==my_complex_data 哪个回报: 1 2 Initial complex data {'keyC': [1,'b': 2}} * ENCODE * 99699012300340107010101210067003400580032009100490044003200500044003200510093004400320034010701010121006600340058003200500044003200340107010101210065003400580032004900440032003401070101012100680034005800320123003400970034005800320049004400320034009800340058003200500125012599699 need to declare 32 bit words 9.0 times block 0 content 99699012300340107010101210067003 - substorage keyComplex_000 block 1 content 40058003200910049004400320050004 - substorage keyComplex_001 block 2 content 40032005100930044003200340107010 - substorage keyComplex_002 block 3 content 10121006600340058003200500044003 - substorage keyComplex_003 block 4 content 20034010701010121006500340058003 - substorage keyComplex_004 block 5 content 20049004400320034010701010121006 - substorage keyComplex_005 block 6 content 80034005800320123003400970034005 - substorage keyComplex_006 block 7 content 80032004900440032003400980034005 - substorage keyComplex_007 block 8 content 8003200500125012599699 - substorage keyComplex_008 * DECODE * keyComplex_000 99699012300340107010101210067003 keyComplex_001 40058003200910049004400320050004 keyComplex_002 40032005100930044003200340107010 keyComplex_003 10121006600340058003200500044003 keyComplex_004 20034010701010121006500340058003 keyComplex_005 20049004400320034010701010121006 keyComplex_006 80034005800320123003400970034005 keyComplex_007 80032004900440032003400980034005 keyComplex_008 8003200500125012599699 ok 3 Extracted complex data from blockchain {'keyC': [1,'b': 2}} Integrity test pass: True (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |