def test_checkwitness(self): """ 测试CheckWitness功能以及使用方法 :return: """ code = '59c56b6a00527ac46a51527ac46a00c304746573749c6409006a51c3652700616a00c30574657374319c640900650b006c756661006c756653c56b04746573746c75660113c56b6a00527ac401610162016353c176c96a51527ac4681653797374656d2e52756e74696d652e47657454696d65616a52527ac46a52c3681553797374656d2e52756e74696d652e4e6f74696679616a52c3a76a53527ac46a53c3539753976a53527ac46a53c300876426006a51c36a53c3c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a53c351876426006a51c36a53c3c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a53c352a26424006a51c352c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a53c3681553797374656d2e52756e74696d652e4e6f746966796151681553797374656d2e52756e74696d652e4e6f7469667961006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566' addr = Address.address_from_vm_code(code) abi = '{"functions":[{"name":"Main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"check","parameters":[{"name":"acc","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') acc1 = sdk.get_wallet_manager().get_account( 'AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve', '060708') func = abi_info.get_function('check') func.set_params_value(acc1.get_address().to_byte_array()) res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc, acc, 200000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res)
def test_input_list(self): code = '59c56b6a00527ac46a51527ac451681553797374656d2e52756e74696d652e4e6f74696679616a00c305746f5f73639c64270052681553797374656d2e52756e74696d652e4e6f74696679616a51c300c3650b006c756661006c756660c56b6a00527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a51527ac41400000000000000000000000000000000000000016a52527ac46a00c3681b53797374656d2e52756e74696d652e436865636b5769746e6573736163200000681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a00c36a51c35a53c176c96a53527ac4516a52c3087472616e736665726a53c351c176c9537951795572755172755279527954727552727568164f6e746f6c6f67792e4e61746976652e496e766f6b65616a54527ac46a54c3681553797374656d2e52756e74696d652e4e6f74696679616a54c36439006a54c301019c643000107472616e736665722073756363656564681553797374656d2e52756e74696d652e4e6f7469667961516c7566610f7472616e73666572206661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c7566006c7566' addr = Address.address_from_vm_code(code) abi = '{"functions":[{"name":"Main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"test","parameters":[{"name":"arr","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') acc1 = sdk.get_wallet_manager().get_account( 'AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve', '060708') func = abi_info.get_function('test') func.set_params_value([[ acc.get_address().to_byte_array(), acc.get_address().to_byte_array(), 3 ], [ acc.get_address().to_byte_array(), acc.get_address().to_byte_array(), 1 ]]) res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc1, acc1, 200000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res)
def test_invoke_a_b(self): code_b = "59c56b6a00527ac46a51527ac46a00c308696e766f6b655f619c640b006a51c300c3656e00616a00c309696e766f6b655f61319c640e006a51c300c3650b006c756661006c756656c56b6a00527ac46a00c3026f700461726773527268174e656f2e4170702e526567697374657241707043616c6c616a51527ac46a51c3057465737431006a52527ac46a52c36c756656c56b6a00527ac46a00c3026f700461726773527268174e656f2e4170702e526567697374657241707043616c6c616a51527ac46a51c30474657374037374686a52527ac46a52c3681553797374656d2e52756e74696d652e4e6f7469667961006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566" code_a = "59c56b6a00527ac46a51527ac46a00c304746573749c6409006a51c3652700616a00c30574657374319c640900650b006c756661006c756653c56b04746573746c756654c56b6a00527ac46a00c3681553797374656d2e52756e74696d652e4e6f7469667961006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566" abi_b = '{"functions":[{"name":"main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"invoke_a","parameters":[{"name":"addr","type":""}],"returntype":""},{"name":"invoke_a1","parameters":[{"name":"addr","type":""}],"returntype":""},{"name":"makeState","parameters":[{"name":"fromacct","type":""},{"name":"toacct","type":""},{"name":"amount","type":""}],"returntype":""}]}' abi_a = '{"functions":[{"name":"main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"test","parameters":[{"name":"args","type":""}],"returntype":""},{"name":"test1","parameters":[{"name":"","type":""}],"returntype":""}]}' addr_b = Address.address_from_vm_code(code_b) addr_a = Address.address_from_vm_code(code_a) abi_b = json.loads(abi_b) abi_info_b = AbiInfo('0x' + addr_b.to_reverse_hex_str(), 'main', abi_b['functions'], []) abi_a = json.loads(abi_a) abi_info_a = AbiInfo('0x' + addr_a.to_reverse_hex_str(), 'main', abi_a['functions'], []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') func = abi_info_b.get_function('invoke_a') func.set_params_value((addr_a.to_reverse_hex_str(), )) res = sdk.neo_vm().send_transaction(addr_b.to_array(), acc, acc, 200000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res)
def test_domain(self): """ :return: """ code = '012cc56b6a00527ac46a51527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a52527ac46a00c30872656769737465729c647a006a51c300c36a53527ac46a51c351c36a54527ac46a53c3681b53797374656d2e52756e74696d652e436865636b5769746e657373616410006a53c36a54c37c65ac0b6c75666114436865636b5769746e657373206661696c656421681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a00c30473656c6c9c6488006a51c300c36a53527ac46a51c351c36a54527ac46a51c352c36a55527ac46a53c3681b53797374656d2e52756e74696d652e436865636b5769746e657373616414006a53c36a54c36a55c3527265bb096c75666114436865636b5769746e657373206661696c656421681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a00c30571756572799c6416006a51c300c36a54527ac46a54c365f2086c7566616a00c3036275799c6488006a51c300c36a53527ac46a51c351c36a54527ac46a51c352c36a55527ac46a53c3681b53797374656d2e52756e74696d652e436865636b5769746e657373616414006a53c36a54c36a55c352726571056c75666114436865636b5769746e657373206661696c656421681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a00c304646f6e659c647a006a51c300c36a53527ac46a51c351c36a54527ac46a53c3681b53797374656d2e52756e74696d652e436865636b5769746e657373616410006a53c36a54c37c65a6006c75666114436865636b5769746e657373206661696c656421681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a00c3087472616e736665729c6428006a51c300c36a56527ac46a51c351c36a57527ac46a56c36a52c36a57c35272651f036c7566611a4e6f74206120737570706f72746564206f7065726174696f6e21681553797374656d2e52756e74696d652e4e6f7469667961516c7566011cc56b6a00527ac46a51527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a52527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a53527ac41400000000000000000000000000000000000000016a54527ac46a52c36a51c37c681253797374656d2e53746f726167652e476574616a55527ac46a55c36a53c39e642b000b6e6f7420696e2073656c6c681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a52c30f4f726967696e616c5f4f776e65725f6a51c37e7c681253797374656d2e53746f726167652e476574616a56527ac46a56c36a00c39e642900096e6f74206f776e6572681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a52c30650726963655f6a51c37e7c681253797374656d2e53746f726167652e476574616a57527ac46a53c36a00c36a57c353c176c96a58527ac4516a54c3087472616e736665726a58c351c176c9537951795572755172755279527954727552727568164f6e746f6c6f67792e4e61746976652e496e766f6b65616a59527ac46a59c364f7006a59c301019c64ee006a52c30354505f6a51c37e7c681253797374656d2e53746f726167652e476574616a5a527ac46a52c36a51c36a5ac35272681253797374656d2e53746f726167652e507574616a52c30354505f6a51c37e7c681553797374656d2e53746f726167652e44656c657465616a52c30650726963655f6a51c37e7c681553797374656d2e53746f726167652e44656c657465616a52c30f4f726967696e616c5f4f776e65725f6a51c37e7c681553797374656d2e53746f726167652e44656c657465610d646f6e65207375636365656421681553797374656d2e52756e74696d652e4e6f7469667961516c7566610f7472616e73666572206661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c7566006c75660111c56b6a00527ac46a51527ac46a52527ac41400000000000000000000000000000000000000016a53527ac46a00c3681b53797374656d2e52756e74696d652e436865636b5769746e6573736164e2006a00c36a51c36a52c353c176c96a54527ac4516a53c3087472616e736665726a54c351c176c9537951795572755172755279527954727552727568164f6e746f6c6f67792e4e61746976652e496e766f6b65616a55527ac46a55c3681553797374656d2e52756e74696d652e4e6f74696679616a55c36439006a55c301019c643000107472616e736665722073756363656564681553797374656d2e52756e74696d652e4e6f7469667961516c7566610f7472616e73666572206661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c75666234006113636865636b5769746e657373206661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c756661006c75660123c56b6a00527ac46a51527ac46a52527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a53527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a54527ac46a53c36a51c37c681253797374656d2e53746f726167652e476574616a55527ac46a55c36a54c39e6430001075726c206e6f7420696e2073616c6521681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a53c30354505f6a51c37e7c681253797374656d2e53746f726167652e476574616a56527ac46a53c30650726963655f6a51c37e7c681253797374656d2e53746f726167652e476574616a57527ac46a56c3630b016a52c36a57c3a264c2006a00c36a54c36a52c35272656efd6484006a53c30354505f6a51c37e6a00c35272681253797374656d2e53746f726167652e507574616a52c36a57c3a0642b006a53c30650726963655f6a51c37e6a52c35272681253797374656d2e53746f726167652e50757461610c627579207375636365656421681553797374656d2e52756e74696d652e4e6f7469667961516c7566610f5472616e73666572204661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c756661215072696365206973206c6f776572207468616e2063757272656e74207072696365681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a52c36a57c3a1644100215072696365206973206c6f776572207468616e2063757272656e74207072696365681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a54c36a00c36a57c352726526fc647c006a53c30354505f6a51c37e6a00c35272681253797374656d2e53746f726167652e507574616a53c30650726963655f6a51c37e6a52c35272681253797374656d2e53746f726167652e507574610f726566756e64207375636365656421681553797374656d2e52756e74696d652e4e6f7469667961516c7566610d726566756e64206661696c6564681553797374656d2e52756e74696d652e4e6f7469667961006c7566006c756657c56b6a00527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a51527ac46a51c36a00c37c681253797374656d2e53746f726167652e476574616a52527ac4096f776e6572206973206a52c37e681553797374656d2e52756e74696d652e4e6f74696679616a52c36c756660c56b6a00527ac46a51527ac46a52527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a53527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a54527ac46a53c36a51c37c681253797374656d2e53746f726167652e476574616a55527ac46a55c36a00c39c64a6006a53c30f4f726967696e616c5f4f776e65725f6a51c37e6a00c35272681253797374656d2e53746f726167652e507574616a53c30650726963655f6a51c37e6a52c35272681253797374656d2e53746f726167652e507574616a53c36a51c36a54c35272681253797374656d2e53746f726167652e507574610d73656c6c207375636365656421681553797374656d2e52756e74696d652e4e6f7469667961516c7566610b4e6f742061206f776e6572681553797374656d2e52756e74696d652e4e6f7469667961006c75665bc56b6a00527ac46a51527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a52527ac46a52c36a51c37c681253797374656d2e53746f726167652e476574616351006a52c36a51c36a00c35272681253797374656d2e53746f726167652e50757461117265676973746572207375636365656421681553797374656d2e52756e74696d652e4e6f7469667961516c75666113616c7265616479207265676973746572656421681553797374656d2e52756e74696d652e4e6f7469667961006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566' addr = Address.address_from_vm_code(code) abi = '{"functions":[{"name":"main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"to_sc","parameters":[{"name":"acc","type":""},{"name":"acc1","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') acc1 = sdk.get_wallet_manager().get_account( 'AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve', '060708') func = abi_info.get_function('buy') func.set_params_value(acc1.get_address().to_byte_array(), 'zou', 2) res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc1, acc1, 200000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res)
def __send_init(self, acct: Account, payer_acct: Account, gas_limit: int, gas_price: int, pre_exec=False): if self.contract_addr is None or self.contract_addr == "": raise Exception("null code_address") abi = json.loads(self.nep5_abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo(abi.hash, abi.entrypoint, abi.functions, abi.events) func = abi_info.get_function("init") if pre_exec: params = BuildParams.serialize_abi_function(func) unix_time_now = int(time()) tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, bytearray(), params, bytearray(), [], bytearray()) if acct is not None: self.__sdk.sign_transaction(tx, acct) obj = self.__sdk.rpc.send_raw_transaction_pre_exec(tx) if int(obj["Result"]) is not 1: raise Exception("send_raw_transaction PreExec error:", obj) return obj["Gas"] if acct is None or payer_acct is None: raise Exception("acct or payer_acct should not be None") return self.__sdk.neo_vm().send_transaction( bytearray(self.contract_addr), acct, payer_acct, gas_limit, gas_price, func, pre_exec)
def __get_abi_from_file(self, abi_file): f = open(abi_file) abi_str = f.readline() abi = json.loads(abi_str, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) self.abi_info = AbiInfo("0x" + self.code_addr, "main", abi.functions, [])
def test_init(self): abi = json.loads(abi_str) abi_info = AbiInfo(abi['hash'], abi['entrypoint'], abi['functions'], abi['events']) func = abi_info.get_function("init") contract_address = bytearray.fromhex("bc9795db0abe9d2d9ea565286a237dbf6b407165") contract_address.reverse() res = sdk.neo_vm().send_transaction(contract_address, acc, acc, 20000, 0, func, False) time.sleep(6) print(sdk.rpc.get_smart_contract_event_by_tx_hash(res))
def test_get_function(self): str_abi = '{"hash":"0x362cb5608b3eca61d4846591ebb49688900fedd0","entrypoint":"Main","functions":' \ '[{"name":"Main","parameters":[{"name":"operation","type":"String"},{"name":"args",' \ '"type":"Array"}],"returntype":"Any"},{"name":"Hello","parameters":[{"name":"msg",' \ '"type":"String"}],"returntype":"Void"}],"events":[]}' dict_abi = json.loads(str_abi) abi_info = AbiInfo(dict_abi['hash'], dict_abi['entrypoint'], dict_abi['functions'], dict_abi['events']) func_name = 'Hello' func = abi_info.get_function(func_name) self.assertEqual(func_name, func.name)
def make_commit(self, issuerOntid: str, subjectOntid: str, claimId: str, payer: str, gas_limit: int, gas_price: int): # TODO abi = json.loads(self.abi, object_hook=lambda d: namedtuple('X', d.keys())(*d.values())) abi_info = AbiInfo(abi.hash, abi.entrypoint, abi.functions, abi.events) func = abi_info.get_function("Commit") func.set_params_value(bytes(claimId.encode()), bytes(issuerOntid.encode()), bytes(subjectOntid.encode())) params = BuildParams.serialize_abi_function(func) unix_time_now = int(time()) return Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, Address.b58decode(payer), params, bytearray(), [], bytearray())
def __update_abi_info(self): try: entry_point = self.__oep4_abi['entrypoint'] except KeyError: entry_point = '' functions = self.__oep4_abi['functions'] try: events = self.__oep4_abi['events'] except KeyError: events = list() self.__abi_info = AbiInfo(self.get_contract_address(is_hex=True), entry_point, functions, events)
def build_params(): abi = AbiInfo(nep5abi['hash'], nep5abi['entrypoint'], nep5abi["functions"]) # func = abi.get_function("Transfer") # func = abi.get_function("BalanceOf") func = abi.get_function("balanceOf") # func = abi.get_function("deploy") # func.set_params_value((acct1.get_address().to_array(), acct2.get_address().to_array(), 19 * 10000000)) # add = acct1.get_address().to_reverse_hex_str() func.set_params_value( (Address.b58decode('AHX1wzvdw9Yipk7E9MuLY4GGX4Ym9tHeDe').to_array(), )) params = BuildParams.serialize_abi_function(func) params += bytearray([0x67]) return params
def test_native_invoke(self): """ 测试向合约打钱和从合约打钱给账户,使用以及功能 :return: """ code = '5dc56b6a00527ac46a51527ac46a00c305746f5f73639c6424006a51c300c36a52527ac46a51c351c36a53527ac46a52c36a53c37c6594016c7566616a00c30766726f6d5f73639c6424006a51c300c36a54527ac46a51c351c36a53527ac46a54c36a53c37c653c006c756661006c756656c56b6a00527ac46a51527ac46a52527ac46a00c36a51c36a52c353c66b6a52527ac46a51527ac46a00527ac46c6c75665cc56b6a00527ac46a51527ac41400000000000000000000000000000000000000016a52527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a53527ac46a53c36a00c36a51c352726568ff6a54527ac4516a52c3087472616e736665726a54c351c176c9537951795572755172755279527954727552727568164f6e746f6c6f67792e4e61746976652e496e766f6b65616a55527ac46a55c3681553797374656d2e52756e74696d652e4e6f74696679616a55c3642f006a55c301019c6426000773756363656564681553797374656d2e52756e74696d652e4e6f746966796162230061066661696c6564681553797374656d2e52756e74696d652e4e6f746966796161006c75665dc56b6a00527ac46a51527ac41400000000000000000000000000000000000000016a52527ac4682d53797374656d2e457865637574696f6e456e67696e652e476574457865637574696e6753637269707448617368616a53527ac46a00c3681b53797374656d2e52756e74696d652e436865636b5769746e6573736164c9006a00c36a53c36a51c35272651dfe6a54527ac4516a52c3087472616e736665726a54c351c176c9537951795572755172755279527954727552727568164f6e746f6c6f67792e4e61746976652e496e766f6b65616a55527ac46a55c3681553797374656d2e52756e74696d652e4e6f74696679616a55c3642f006a55c301019c6426000773756363656564681553797374656d2e52756e74696d652e4e6f746966796162230061066661696c6564681553797374656d2e52756e74696d652e4e6f746966796161006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566' addr = Address.address_from_vm_code(code) abi = '{"functions":[{"name":"Main","parameters":[{"name":"operation","type":""},{"name":"args","type":""}],"returntype":""},{"name":"to_sc","parameters":[{"name":"from_acct","type":""},{"name":"amount","type":""}],"returntype":""},{"name":"from_sc","parameters":[{"name":"to_acc","type":""},{"name":"amount","type":""}],"returntype":""},{"name":"makeState","parameters":[{"name":"fromacct","type":""},{"name":"toacct","type":""},{"name":"amount","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') acc1 = sdk.get_wallet_manager().get_account( 'AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve', '060708') print('acc: %s' % sdk.get_rpc().get_balance(acc.get_address_base58())) func = abi_info.get_function('to_sc') func.set_params_value(acc.get_address().to_byte_array(), 10) res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc, acc, 20000000000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res) print('acc: %s' % sdk.get_rpc().get_balance(acc.get_address_base58())) print() func = abi_info.get_function('from_sc') func.set_params_value(acc.get_address().to_byte_array(), 10) res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc, acc, 20000000000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res) print('acc: %s' % sdk.get_rpc().get_balance(acc.get_address_base58()))
def __update_abi_info(self): functions = self.__abi['functions'] try: events = self.__abi['events'] except KeyError: events = list() self.__abi_info = AbiInfo(self.get_contract_address(is_hex=True), 'main', functions, events)
def test_init(self): str_abi = '{"hash":"0x362cb5608b3eca61d4846591ebb49688900fedd0","entrypoint":"Main","functions":' \ '[{"name":"Main","parameters":[{"name":"operation","type":"String"},{"name":"args",' \ '"type":"Array"}],"returntype":"Any"},{"name":"Hello","parameters":[{"name":"msg",' \ '"type":"String"}],"returntype":"Void"}],"events":[]}' dict_abi = json.loads(str_abi) abi_info = AbiInfo(dict_abi['hash'], dict_abi['entrypoint'], dict_abi['functions'], dict_abi['events']) self.assertTrue(isinstance(abi_info, AbiInfo))
def test_no_param(self): code = '57c56b6a00527ac46a51527ac46a00c304746573749c640900650b006c756661006c756653c56b06726573756c746c7566' addr = Address.address_from_vm_code(code) abi = '{"functions":[{"name":"Main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"test","parameters":[{"name":"","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') func = abi_info.get_function('test') func.set_params_value() res = sdk.neo_vm().send_transaction(addr.to_byte_array(), acc, acc, 200000000, 500, func, True) print(bytes.fromhex(res).decode())
def test_invoke_transaction(self): sdk.set_rpc(rpc_address) code = '54c56b6c766b00527ac46c766b51527ac4616c766b00c36c766b52527ac46c766b52c30548656c6c6f87630600621a' \ '006c766b51c300c36165230061516c766b53527ac4620e00006c766b53527ac46203006c766b53c3616c756651c56b' \ '6c766b00527ac46151c576006c766b00c3c461681553797374656d2e52756e74696d652e4e6f7469667961616c7566' abi_str = '{"hash":"0x362cb5608b3eca61d4846591ebb49688900fedd0","entrypoint":"Main","functions":[{' \ '"name":"Main","parameters":[{"name":"operation","type":"String"},{"name":"args","type":"Array"}],' \ '"returntype":"Any"},{"name":"Hello","parameters":[{"name":"msg","type":"String"}],' \ '"returntype":"Void"}],"events":[]} ' abi = json.loads(abi_str, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo(abi.hash, abi.entrypoint, abi.functions, abi.events) func = abi_info.get_function("Hello") func.set_params_value("value") contract_address = Address.address_from_vm_code(code).to_byte_array() res = sdk.neo_vm().send_transaction(contract_address, None, None, 0, 0, func, True) self.assertEqual(res, '01')
def generate_abi_info(dict_abi: dict) -> AbiInfo: try: contract_address = dict_abi['hash'] functions = dict_abi['functions'] except KeyError: raise PunicaException(PunicaError.abi_file_error) entry_point = dict_abi.get('entrypoint', '') events = dict_abi.get('events', list()) abi_info = AbiInfo(contract_address, entry_point, functions, events) return abi_info
def __init__(self, sdk: OntologySdk, abi: dict, hex_contract_address: str): if not isinstance(sdk, OntologySdk): raise PotException(PotError.invalid_sdk) if not isinstance(abi, dict): raise PotException(PotError.invalid_abi_type) if not isinstance(hex_contract_address, str): raise PotException(PotError.invalid_contract_address_hex_type) if len(hex_contract_address) != 40: raise PotException(PotError.invalid_contract_address_hex_len) self.__sdk = sdk self.__contract_address_hex = hex_contract_address self.__contract_address_bytearray = bytearray( binascii.a2b_hex(hex_contract_address)) self.__contract_address_bytearray.reverse() self.__abi = abi entry_point = self.__abi.get('entrypoint', '') functions = self.__abi['abi']['functions'] events = self.__abi.get('events', list()) self.__abi_info = AbiInfo(hex_contract_address, entry_point, functions, events)
def get_function(params: dict, function_name: str, abi_info: AbiInfo): if function_name == '': raise PunicaException(PunicaError.other_error('function_name should not be nil')) params = Invoke.params_normalize(params) abi_function = abi_info.get_function(function_name) if len(abi_function.parameters) == 0: pass elif len(abi_function.parameters) == 1: abi_function.set_params_value((params,)) elif len(abi_function.parameters) == len(params): abi_function.set_params_value(tuple(params)) return abi_function
def test_use_hash(self): code = '59c56b6a00527ac46a51527ac46a00c304746573749c6409006a51c3652700616a00c30574657374319c640900650b006c756661006c756653c56b04746573746c75660116c56b6a00527ac401610162016353c176c96a51527ac4681653797374656d2e52756e74696d652e47657454696d65616a52527ac4526a53527ac4556a54527ac46a53c36a54c3966a55527ac46a55c3681553797374656d2e52756e74696d652e4e6f74696679616a52c36a56527ac46a56c353976a56527ac46a56c300876426006a51c36a56c3c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a56c351876426006a51c36a56c3c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a56c3529c6424006a51c352c3681553797374656d2e52756e74696d652e4e6f7469667961006c7566616a56c3681553797374656d2e52756e74696d652e4e6f746966796151681553797374656d2e52756e74696d652e4e6f7469667961006c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566' abi = '{"functions":[{"name":"main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"test","parameters":[{"name":"args","type":""}],"returntype":""},{"name":"test1","parameters":[{"name":"","type":""}],"returntype":""}]}' addr = Address.address_from_vm_code(code) abi = json.loads(abi) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'main', abi['functions'], []) acc = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') func = abi_info.get_function('test') func.set_params_value((addr.to_reverse_hex_str(), )) res = sdk.neo_vm().send_transaction(addr.to_array(), acc, acc, 200000000, 500, func, False) json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) while json_res is None: json_res = sdk.get_rpc().get_smart_contract_event_by_tx_hash(res) time.sleep(1) print(json_res) print(res)
class BaseConfig(object): """Base configuration.""" SECRET_KEY = 'd5bacbc0e4b77d048527c51eddb9b930f97ee' DEBUG = False TESTING = False BCRYPT_LOG_ROUNDS = 13 WTF_CSRF_ENABLED = True DEBUG_TB_ENABLED = False DEBUG_TB_INTERCEPT_REDIRECTS = False SQLALCHEMY_TRACK_MODIFICATIONS = False redis_url = "redis://127.0.0.1:6379/0" # flask-mail config MAIL_SERVER = 'smtp.exmail.qq.com' MAIL_PROT = 25 MAIL_USE_TLS = True MAIL_USE_SSL = False MAIL_USERNAME = MAIL_DEFAULT_SENDER = "" MAIL_PASSWORD = "" MAIL_DEBUG = False MAIL_SUPPRESS_SEND = False ROOT_FOLDER = os.path.abspath(basedir) WALLET_PATH = os.path.join(ROOT_FOLDER, 'wallet', 'wallet.json') CONTRACTS_FOLDER = os.path.join(ROOT_FOLDER, 'contract') GAS_LIMIT = 20000000 GAS_PRICE = 500 ONT_RPC_ADDRESS = 'http://45.76.243.92:20336' CONTRACT_ADDRESS_HEX = '' CONTRACT_ADDRESS_BYTEARRAY = bytearray( binascii.a2b_hex(CONTRACT_ADDRESS_HEX)) CONTRACT_ADDRESS_BYTEARRAY.reverse() ONTOLOGY = OntologySdk() ONTOLOGY.rpc.set_address(ONT_RPC_ADDRESS) with open(os.path.join(CONTRACTS_FOLDER, 'copyright.abi.json')) as f: CONTRACT_ABI = json.loads(f.read()) entry_point = CONTRACT_ABI.get('entrypoint', '') functions = CONTRACT_ABI['abi']['functions'] events = CONTRACT_ABI.get('events', list()) ABI_INFO = AbiInfo(CONTRACT_ADDRESS_HEX, entry_point, functions, events) WALLET_MANAGER = WalletManager() WALLET_MANAGER.open_wallet(WALLET_PATH)
def invoke(sdk, m, function_name=None): func_maps = {} for i in dict(m["function"]).values(): if function_name is not None: if i["function_name"] not in function_name: continue func_map = {} param_list = [] func_map["function_name"] = i["function_name"] func_map["pre_exec"] = i["pre_exec"] try: if type(i["function_param"]) is dict: for value in dict(i["function_param"]).values(): if type(value) is list: p_temp = [] for v in list(value): p_temp.append(v) param_list.append(p_temp) else: param_list.append(value) elif type(i["function_param"]) is list: temp_list = [] for para in list(i["function_param"]): if type(para) is dict: temp_list2 = [] for para2 in dict(para).values(): temp_list2.append(para2) temp_list.append(temp_list2) else: temp_list.append(para) param_list.append(temp_list) func_map["param_list"] = param_list except Exception as e: pass if not i["pre_exec"]: try: func_map["signers"] = i["signers"] except AttributeError as e: func_map["signers"] = None func_maps[i["function_name"]] = func_map with open(str(m["abi_path"]), "r") as f: abi = json.loads(f.read()) abi_info = AbiInfo(abi['hash'], abi['entrypoint'], abi['functions'], abi['events']) code_address = str(abi['hash']) if code_address.startswith('0x'): code_address = code_address.replace('0x', '') contract_address = bytearray.fromhex(code_address) m["contract_address"] = contract_address.hex() contract_address.reverse() sdk.wallet_manager.open_wallet(m["wallet_file_path"]) payer = sdk.wallet_manager.get_account(m["payer_address"], m["payer_password"]) func_l = [] no = 0 for func_map in func_maps.values(): if function_name is not None: if func_map["function_name"] not in function_name: continue func = abi_info.get_function(func_map["function_name"]) func_map["return_type"] = func.return_type l = [] l.append(no) no = no + 1 l.append(func_map["function_name"]) l.append(func_map["pre_exec"]) # 用来放参数 temp_l, params = convert_params(func, func_map) l.append(temp_l[:len(temp_l) - 1]) if params is None: l.append("failed") func_l.append(l) continue try: print("") print("invoking, please waiting ...") print("method: " + func_map["function_name"]) if func_map["pre_exec"]: res = send_transaction(sdk, contract_address, None, None, 0, 0, params, True) if res["error"] != 0: print(res["desc"]) l.append(res["desc"]) else: if res["result"]["Result"] is None or res["result"][ "Result"] == "": print("res:", res["result"]["Result"]) l.append("") else: if func_map["return_type"] == "Integer": value = bytearray.fromhex( res["result"]["Result"]) value.reverse() print("res:", int(value.hex(), 16)) l.append(int(value.hex(), 16)) elif func_map["return_type"] == "ByteArray": print("res:", (bytearray.fromhex( res["result"]["Result"]))) l.append(res["result"]["Result"]) else: print("res:", (bytearray.fromhex( res["result"]["Result"])).decode('utf-8')) l.append((bytearray.fromhex( res["result"]["Result"])).decode('utf-8')) else: txhash, err = handle_tx(contract_address, func_map, params, payer, m, sdk) if txhash == "": l.append(err) else: for i in range(10): time2.sleep(1) event = sdk.rpc.get_smart_contract_event_by_tx_hash( txhash) if event is not None: print("txhash:", txhash) print("event:", event) break l.append(txhash) except Exception as e: print("Error:", e) l.append(e) func_l.append(l) save_file(m, "", func_l)
def __update_abi_info(self): entry_point = self.__oep4_abi.get('entrypoint', '') functions = self.__oep4_abi['abi']['functions'] events = self.__oep4_abi.get('events', list()) self.__abi_info = AbiInfo(self.get_contract_address(is_hex=True), entry_point, functions, events)
class Oep4(object): def __init__(self, sdk): self.__sdk = sdk self.__contract_address = bytearray() self.__oep4_abi = { "contractHash": "85848b5ec3b15617e396bdd62cb49575738dd413", "abi": { "functions": [{ "name": "Main", "parameters": [{ "name": "operation", "type": "" }, { "name": "args", "type": "" }], "returntype": "" }, { "name": "init", "parameters": [{ "name": "", "type": "" }], "returntype": "" }, { "name": "name", "parameters": [{ "name": "", "type": "" }], "returntype": "" }, { "name": "symbol", "parameters": [{ "name": "", "type": "" }], "returntype": "" }, { "name": "decimals", "parameters": [{ "name": "", "type": "" }], "returntype": "" }, { "name": "totalSupply", "parameters": [{ "name": "", "type": "" }], "returntype": "" }, { "name": "balanceOf", "parameters": [{ "name": "account", "type": "" }], "returntype": "" }, { "name": "transfer", "parameters": [{ "name": "from_acct", "type": "" }, { "name": "to_acct", "type": "" }, { "name": "amount", "type": "" }], "returntype": "" }, { "name": "transferMulti", "parameters": [{ "name": "args", "type": "" }], "returntype": "" }, { "name": "approve", "parameters": [{ "name": "owner", "type": "" }, { "name": "spender", "type": "" }, { "name": "amount", "type": "" }], "returntype": "" }, { "name": "transferFrom", "parameters": [{ "name": "spender", "type": "" }, { "name": "from_acct", "type": "" }, { "name": "to_acct", "type": "" }, { "name": "amount", "type": "" }], "returntype": "" }, { "name": "allowance", "parameters": [{ "name": "owner", "type": "" }, { "name": "spender", "type": "" }], "returntype": "" }] } } self.__update_abi_info() def set_contract_address(self, contract_address: str or bytearray or bytes): if len(contract_address) == 20: if isinstance(contract_address, bytes): self.__contract_address = bytearray(contract_address) self.__update_abi_info() elif isinstance(contract_address, bytearray): self.__contract_address = contract_address self.__update_abi_info() else: raise SDKException( ErrorCode.param_err( 'the data type of the contract address unsupported.')) elif isinstance(contract_address, str) and len(contract_address) == 40: self.__contract_address = bytearray( binascii.a2b_hex(contract_address)) self.__contract_address.reverse() self.__update_abi_info() else: raise SDKException( ErrorCode.param_err( 'the length of contract address should be 20 bytes.')) def __update_abi_info(self): entry_point = self.__oep4_abi.get('entrypoint', '') functions = self.__oep4_abi['abi']['functions'] events = self.__oep4_abi.get('events', list()) self.__abi_info = AbiInfo(self.get_contract_address(is_hex=True), entry_point, functions, events) def __get_token_setting(self, func_name: str) -> str: func = self.__abi_info.get_function(func_name) res = self.__sdk.neo_vm().send_transaction(self.__contract_address, None, None, 0, 0, func, True) return res @staticmethod def __b58_address_check(b58_address): if not isinstance(b58_address, str): raise SDKException( ErrorCode.param_err( 'the data type of base58 encode address should be the string.' )) if len(b58_address) != 34: raise SDKException( ErrorCode.param_err( 'the length of base58 encode address should be 34 bytes.')) def get_contract_address(self, is_hex: bool = True) -> str or bytearray: if is_hex: array_address = self.__contract_address.copy() array_address.reverse() return binascii.b2a_hex(array_address).decode('ascii') else: return self.__contract_address def get_abi(self) -> dict: return self.__oep4_abi def get_name(self) -> str: """ This interface is used to call the Name method in ope4 that return the name of an oep4 token. :return: the string name of the oep4 token. """ name = self.__get_token_setting('name') return bytes.fromhex(name).decode() def get_symbol(self) -> str: """ This interface is used to call the Symbol method in ope4 that return the symbol of an oep4 token. :return: a short string symbol of the oep4 token """ get_symbol = self.__get_token_setting('symbol') return bytes.fromhex(get_symbol).decode() def get_decimal(self) -> int: """ This interface is used to call the Decimal method in ope4 that return the number of decimals used by the oep4 token. :return: the number of decimals used by the oep4 token. """ decimals = self.__get_token_setting('decimals') return int(decimals[:2], 16) def init(self, acct: Account, payer_acct: Account, gas_limit: int, gas_price: int) -> str: """ This interface is used to call the TotalSupply method in ope4 that initialize smart contract parameter. :param acct: an Account class that used to sign the transaction. :param payer_acct: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('init') tx_hash = self.__sdk.neo_vm().send_transaction(self.__contract_address, acct, payer_acct, gas_limit, gas_price, func, False) return tx_hash def get_total_supply(self) -> int: """ This interface is used to call the TotalSupply method in ope4 that return the total supply of the oep4 token. :return: the total supply of the oep4 token. """ total_supply = self.__get_token_setting('totalSupply') array = bytearray(binascii.a2b_hex(total_supply.encode('ascii'))) array.reverse() try: supply = int(binascii.b2a_hex(array).decode('ascii'), 16) except ValueError: supply = 0 return supply def balance_of(self, b58_address: str) -> int: """ This interface is used to call the BalanceOf method in ope4 that query the ope4 token balance of the given base58 encode address. :param b58_address: the base58 encode address. :return: the oep4 token balance of the base58 encode address. """ func = self.__abi_info.get_function('balanceOf') Oep4.__b58_address_check(b58_address) address = Address.b58decode(b58_address).to_array() func.set_params_value((address, )) balance = self.__sdk.neo_vm().send_transaction(self.__contract_address, None, None, 0, 0, func, True) array = bytearray(binascii.a2b_hex(balance.encode('ascii'))) array.reverse() try: balance = int(binascii.b2a_hex(array).decode('ascii'), 16) except ValueError: balance = 0 return balance def transfer(self, from_acct: Account, b58_to_address: str, value: int, payer_acct: Account, gas_limit: int, gas_price: int) -> str: """ This interface is used to call the Transfer method in ope4 that transfer an amount of tokens from one account to another account. :param from_acct: an Account class that send the oep4 token. :param b58_to_address: a base58 encode address that receive the oep4 token. :param value: an int value that indicate the amount oep4 token that will be transferred in this transaction. :param payer_acct: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('transfer') if not isinstance(value, int): raise SDKException( ErrorCode.param_err('the data type of value should be int.')) if value < 0: raise SDKException( ErrorCode.param_err( 'the value should be equal or great than 0.')) if not isinstance(from_acct, Account): raise SDKException( ErrorCode.param_err( 'the data type of from_acct should be Account.')) Oep4.__b58_address_check(b58_to_address) from_address = from_acct.get_address().to_array() to_address = Address.b58decode(b58_to_address).to_array() params = (from_address, to_address, value) func.set_params_value(params) tx_hash = self.__sdk.neo_vm().send_transaction(self.__contract_address, from_acct, payer_acct, gas_limit, gas_price, func, False) return tx_hash def transfer_multi(self, args: list, payer_acct: Account, signers: list, gas_limit: int, gas_price: int): """ This interface is used to call the TransferMulti method in ope4 that allow transfer amount of token from multiple from-account to multiple to-account multiple times. :param args: a parameter list with each item contains three sub-items: base58 encode transaction sender address, base58 encode transaction receiver address, amount of token in transaction. :param payer_acct: an Account class that used to pay for the transaction. :param signers: a signer list used to sign this transaction which should contained all sender in args. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('transferMulti') for index in range(len(args)): item = args[index] Oep4.__b58_address_check(item[0]) Oep4.__b58_address_check(item[1]) if not isinstance(item[2], int): raise SDKException( ErrorCode.param_err( 'the data type of value should be int.')) if item[2] < 0: raise SDKException( ErrorCode.param_err( 'the value should be equal or great than 0.')) from_address_array = Address.b58decode(item[0]).to_array() to_address_array = Address.b58decode(item[1]).to_array() args[index] = [from_address_array, to_address_array, item[2]] func.set_params_value((args, )) params = BuildParams.serialize_abi_function(func) unix_time_now = int(time.time()) params.append(0x67) for i in self.__contract_address: params.append(i) signers_len = len(signers) if signers_len == 0: raise SDKException(ErrorCode.param_err('payer account is None.')) payer_address = payer_acct.get_address().to_array() tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_address, params, bytearray(), [], bytearray()) for index in range(signers_len): self.__sdk.add_sign_transaction(tx, signers[index]) tx_hash = self.__sdk.rpc.send_raw_transaction(tx) return tx_hash def approve(self, owner_acct: Account, b58_spender_address: str, amount: int, payer_acct: Account, gas_limit: int, gas_price: int): """ This interface is used to call the Approve method in ope4 that allows spender to withdraw a certain amount of oep4 token from owner account multiple times. If this function is called again, it will overwrite the current allowance with new value. :param owner_acct: an Account class that indicate the owner. :param b58_spender_address: a base58 encode address that be allowed to spend the oep4 token in owner's account. :param amount: an int value that indicate the amount oep4 token that will be transferred in this transaction. :param payer_acct: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('approve') if not isinstance(amount, int): raise SDKException( ErrorCode.param_err('the data type of amount should be int.')) if amount < 0: raise SDKException( ErrorCode.param_err( 'the amount should be equal or great than 0.')) owner_address = owner_acct.get_address().to_array() Oep4.__b58_address_check(b58_spender_address) spender_address = Address.b58decode(b58_spender_address).to_array() params = (owner_address, spender_address, amount) func.set_params_value(params) tx_hash = self.__sdk.neo_vm().send_transaction(self.__contract_address, owner_acct, payer_acct, gas_limit, gas_price, func, False) return tx_hash def allowance(self, b58_owner_address: str, b58_spender_address: str): """ This interface is used to call the Allowance method in ope4 that query the amount of spender still allowed to withdraw from owner account. :param b58_owner_address: a base58 encode address that represent owner's account. :param b58_spender_address: a base58 encode address that represent spender's account. :return: the amount of oep4 token that owner allow spender to transfer from the owner account. """ func = self.__abi_info.get_function('allowance') Oep4.__b58_address_check(b58_owner_address) owner = Address.b58decode(b58_owner_address).to_array() Oep4.__b58_address_check(b58_spender_address) spender = Address.b58decode(b58_spender_address).to_array() func.set_params_value((owner, spender)) allowance = self.__sdk.neo_vm().send_transaction( self.__contract_address, None, None, 0, 0, func, True) array = bytearray(binascii.a2b_hex(allowance.encode('ascii'))) array.reverse() try: allowance = int(binascii.b2a_hex(array).decode('ascii'), 16) except ValueError: allowance = 0 return allowance def transfer_from(self, spender_acct: Account, b58_from_address: str, b58_to_address: str, value: int, payer_acct: Account, gas_limit: int, gas_price: int): """ This interface is used to call the Allowance method in ope4 that allow spender to withdraw amount of oep4 token from from-account to to-account. :param spender_acct: an Account class that actually spend oep4 token. :param b58_from_address: an base58 encode address that actually pay oep4 token for the spender's spending. :param b58_to_address: a base58 encode address that receive the oep4 token. :param value: the amount of ope4 token in this transaction. :param payer_acct: an Account class that used to pay for the transaction. :param gas_limit: an int value that indicate the gas limit. :param gas_price: an int value that indicate the gas price. :return: the hexadecimal transaction hash value. """ func = self.__abi_info.get_function('transferFrom') Oep4.__b58_address_check(b58_from_address) Oep4.__b58_address_check(b58_to_address) if not isinstance(spender_acct, Account): raise SDKException( ErrorCode.param_err( 'the data type of spender_acct should be Account.')) spender_address_array = spender_acct.get_address().to_array() from_address_array = Address.b58decode(b58_from_address).to_array() to_address_array = Address.b58decode(b58_to_address).to_array() if not isinstance(value, int): raise SDKException( ErrorCode.param_err('the data type of value should be int.')) params = (spender_address_array, from_address_array, to_address_array, value) func.set_params_value(params) params = BuildParams.serialize_abi_function(func) unix_time_now = int(time.time()) params.append(0x67) for i in self.__contract_address: params.append(i) if payer_acct is None: raise SDKException(ErrorCode.param_err('payer account is None.')) payer_address_array = payer_acct.get_address().to_array() tx = Transaction(0, 0xd1, unix_time_now, gas_price, gas_limit, payer_address_array, params, bytearray(), [], bytearray()) self.__sdk.sign_transaction(tx, spender_acct) if spender_acct.get_address_base58() != payer_acct.get_address_base58( ): self.__sdk.add_sign_transaction(tx, payer_acct) tx_hash = self.__sdk.rpc.send_raw_transaction(tx) return tx_hash
# ------------------------------------------- # GLOBAL SETTINGS # ------------------------------------------- rpc_addr = 'http://polaris3.ont.io:20336' sdk = OntologySdk() sdk.set_rpc(rpc_addr) sdk.open_wallet('/Users/zou/PycharmProjects/ont_test/ont_contrast/demo/cli/wallet.json') code = '' addr = Address.address_from_vm_code(code) contract_addr = addr.to_array() abi = '{"functions":[{"name":"main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"init","parameters":[{"name":"seed","type":""}],"returntype":""},{"name":"next_round","parameters":[{"name":"seed","type":""}],"returntype":""},{"name":"shoot","parameters":[{"name":"off_player","type":""},{"name":"def_player","type":""},{"name":"seconds","type":""},{"name":"team","type":""}],"returntype":""},{"name":"pass_ball","parameters":[{"name":"holder","type":""},{"name":"def_player","type":""},{"name":"team","type":""}],"returntype":""},{"name":"get_scores","parameters":[{"name":"","type":""}],"returntype":""},{"name":"get_curr_time","parameters":[{"name":"","type":""}],"returntype":""},{"name":"get_team_scores","parameters":[{"name":"","type":""}],"returntype":""},{"name":"pick_ball_holder","parameters":[{"name":"team","type":""},{"name":"is_first","type":""}],"returntype":""},{"name":"jump_ball","parameters":[{"name":"","type":""}],"returntype":""},{"name":"rand_player","parameters":[{"name":"team","type":""}],"returntype":""},{"name":"random_int_from_zero","parameters":[{"name":"num","type":""},{"name":"seed","type":""}],"returntype":""}]}' abi = json.loads(abi) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'main', abi['functions'], []) acc1 = sdk.get_wallet_manager().get_account('ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') def get_from_hex(res): """ hex to string :param res: :return: """ return util.parse_neo_vm_contract_return_type_string(res) def get_integer_from_hex(res): """
ontology = OntologySdk() remote_rpc_address = 'http://polaris3.ont.io:20336' contract_address_hex = '9026b8595d5c97a3ffb41d9c7aadaccfde82c40b' contract_address_bytearray = bytearray(binascii.a2b_hex(contract_address_hex)) contract_address_bytearray.reverse() ontology.set_rpc(remote_rpc_address) root_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) wallet_path = os.path.join(root_folder, 'wallet', 'wallet.json') contracts_folder = os.path.join(root_folder, 'contracts') contracts_path = os.path.join(contracts_folder, 'interplanetary-album.json') with open(contracts_path) as f: contract_abi = json.loads(f.read()) entry_point = contract_abi.get('entrypoint', '') functions = contract_abi['abi']['functions'] events = contract_abi.get('events', list()) abi_info = AbiInfo(contract_address_hex, entry_point, functions, events) wallet_manager = WalletManager() wallet_manager.open_wallet(wallet_path) password = input('password: '******'AKeDu9QW6hfAhwpvCwNNwkEQt1LkUQpBpW', password) ont_id_acct = wallet_manager.get_account( 'did:ont:AHBB3LQNpqXjCLathy7vTNgmQ1cGSj8S9Z', password) class TestSmartContract(unittest.TestCase): def test_put_one_item(self): ipfs_address = 'QmaxL3ixbfG1mwQeKRdBPnYxqiESv5nkKg5UoppdvtZPfn' ext = '.jpg'
def main(argv): try: opts, args = getopt.getopt(argv, "hm:i:", ["migrate=", "invoke="]) except getopt.GetoptError: print('test.py [-m|--migrate] [-i|--invoke] ') sys.exit(2) m = {} for opt, arg in opts: if opt == '-h': print('test.py [-m|--migrate] [-i|--invoke] ') sys.exit() elif opt in ("-m", "--migrate"): m["func"] = "migrate" if "json" in str(arg): with open(arg, "r") as f: r = json.load( f, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) m["rpc_address"] = r.rpc_address m["need_storage"] = r.need_storage m["name"] = r.name m["code_version"] = r.code_version m["author"] = r.author m["email"] = r.email m["desp"] = r.desp m["payer_address"] = r.payer_address m["payer_password"] = r.payer_password m["wallet_file_path"] = r.wallet_file_path m["gas_limit"] = r.gas_limit m["gas_price"] = r.gas_price m["save_file"] = r.save_file if ".avm" in r.code: with open(r.code, "r") as f2: m["code"] = f2.read() else: m["code"] = r.code m["contract_address"] = Address.address_from_vm_code( m["code"]).to_hex_str() else: temp = str(arg).split(",") for i in temp: t = str(i).split("=") m[t[0]] = t[1] elif opt in ("-i", "--invoke"): m["func"] = "invoke" if "json" in str(arg): with open(arg, "r") as f: r = json.load( f, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) m["rpc_address"] = r.rpc_address m["acct_address"] = r.acct_address m["acct_password"] = r.acct_password m["payer_address"] = r.payer_address m["payer_password"] = r.payer_password m["wallet_file_path"] = r.wallet_file_path m["gas_limit"] = r.gas_limit m["gas_price"] = r.gas_price m["abi_path"] = r.abi_path m["save_file"] = r.save_file m["function"] = r.function else: temp = str(arg).split(",") for i in temp: t = str(i).split("=") m[t[0]] = t[1] else: print('test.py [-m|--migrate] [-i|--invoke] ') sys.exit() sdk = OntologySdk() sdk.set_rpc(m["rpc_address"]) if m["func"] is "migrate": need_storage = False if m["need_storage"] is 'true': need_storage = True tx = sdk.neo_vm().make_deploy_transaction( m["code"], need_storage, m["name"], m["code_version"], m["author"], m["email"], m["desp"], m["payer_address"], m["gas_limit"], m["gas_price"]) sdk.wallet_manager.open_wallet(m["wallet_file_path"]) acct = sdk.wallet_manager.get_account(m["payer_address"], m["payer_password"]) sdk.sign_transaction(tx, acct) sdk.set_rpc(m["rpc_address"]) try: print("deploying,please waiting ...") res = sdk.rpc.send_raw_transaction(tx) print("txhash:", res) for i in range(10): time.sleep(1) res = sdk.rpc.get_smart_contract(m["contract_address"]) if res == "": continue else: print("deploy success") break save_file(m, "success") except Exception as e: print(e) save_file(m, e) elif m["func"] is "invoke": func_map = {} t = 0 for i in list(m["function"]): func_list = [] func_list.append(i.function_name) func_list.append(i.pre_exec) for j in list(i.function_param): func_list.append(j) func_map["function" + str(t)] = func_list t = t + 1 with open(str(m["abi_path"]), "r") as f: abi = json.loads(f.read(), object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) abi_info = AbiInfo(abi.hash, abi.entrypoint, abi.functions, abi.events) contract_address = bytearray.fromhex(str(abi.hash)[2:]) m["contract_address"] = contract_address.hex() contract_address.reverse() sdk.wallet_manager.open_wallet(m["wallet_file_path"]) acct = sdk.wallet_manager.get_account(m["acct_address"], m["acct_password"]) payer = sdk.wallet_manager.get_account(m["payer_address"], m["payer_password"]) func_l = [] for func_info in func_map.values(): func = abi_info.get_function(func_info[0]) params = [] l = [] l.append(func_info[0]) l.append(func_info[1]) temp_l = "" for i in range(len(func_info)): if i == 0 or i == 1: continue temp_l += func_info[i] + ":" if func.parameters[i - 2].type == "String": params.append(str(func_info[i])) if func.parameters[i - 2].type == "ByteArray": params.append(bytearray(func_info[i].encode())) if func.parameters[i - 2].type == "Integer": params.append(func_info[i]) l.append(temp_l[:len(temp_l) - 1]) if len(params) == 1: func.set_params_value(params[0]) elif len(params) == 2: func.set_params_value(params[0], params[1]) elif len(params) == 3: func.set_params_value(params[0], params[1], params[2]) elif len(params) == 4: func.set_params_value(params[0], params[1], params[2], params[3]) elif len(params) == 5: func.set_params_value(params[0], params[1], params[2], params[3], params[4]) elif len(params) == 6: func.set_params_value(params[0], params[1], params[2], params[3], params[4], params[5]) elif len(params) == 7: func.set_params_value(params[0], params[1], params[2], params[3], params[4], params[5], params[6]) pre_exec = False if func_info[1] == "true": pre_exec = True try: print("") print("invoking, please waiting ...") print("method: " + func_info[0]) res = sdk.neo_vm().send_transaction( contract_address, acct, payer, m["gas_limit"], m["gas_price"], func, pre_exec) if not pre_exec: time.sleep(6) print("txhash:", res) print("Event:", sdk.rpc.get_smart_contract_event_by_tx_hash(res)) l.append(res) else: print(res) print("res:", (bytearray.fromhex(res)).decode('utf-8')) l.append((bytearray.fromhex(res)).decode('utf-8')) except Exception as e: print("Error:", e) l.append(e) func_l.append(l) save_file(m, "", func_l) else: print("only support migrate and invoke")
# GLOBAL SETTINGS # ------------------------------------------- rpc_addr = 'http://polaris3.ont.io:20336' sdk = OntologySdk() sdk.set_rpc(rpc_addr) sdk.open_wallet( '/Users/zou/PycharmProjects/ont_test/ont_contrast/demo/cli/wallet.json') code = '0133c56b6a00527ac46a51527ac46a00c304696e69749c64090065fb086c7566616a00c30c746f74616c5f737570706c799c6409006525026c7566616a00c3046e616d659c6409006500026c7566616a00c30673796d626f6c9c640900651e026c7566616a00c3087472616e736665729c6440006a51c3c0539e640700006c7566616a51c300c36a52527ac46a51c351c36a53527ac46a51c352c36a54527ac46a52c36a53c36a54c3527265c0066c7566616a00c30e7472616e736665725f6d756c74699c640e006a51c300c36533066c7566616a00c307617070726f76659c645a006a51c3c0539e640700006c7566616a51c300c36a55527ac46a51c351c36a56527ac46a55c3c001149e630d006a56c3c001149e64080061006c7566616a51c352c36a54527ac46a55c36a56c36a54c352726529046c7566616a00c30d7472616e736665725f66726f6d9c6483006a51c3c0549e640700006c7566616a51c300c36a56527ac46a51c351c36a52527ac46a51c352c36a53527ac46a56c3c001149e6317006a52c3c001149e630d006a53c3c001149e64080061006c7566616a51c353c36a54527ac46a56c36a52c36a53c36a54c35379517955727551727552795279547275527275652f016c7566616a00c30a62616c616e63655f6f669c641c006a51c3c0519e640700006c7566616a51c300c365b7046c7566616a00c309616c6c6f77616e63659c6422006a51c3c0529e640700006c7566616a51c300c36a51c351c37c6575006c7566616a00c307646563696d616c9c6409006550006c756661006c756654c56b036368656a00527ac46a00c36c756655c56b0400e1f5056a00527ac40400e1f5056a51527ac46a51c36a00c3956c756654c56b036368656a00527ac46a00c36c756654c56b586a00527ac46a00c36c756657c56b6a00527ac46a51527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a52527ac40202206a53527ac46a52c36a53c36a00c37e6a51c37e7c681253797374656d2e53746f726167652e476574616c75660121c56b6a00527ac46a51527ac46a52527ac46a53527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a54527ac4144756c9dd829b2142883adbe1ae4f8689a1f673e96a55527ac401016a56527ac40202206a57527ac46a53c3009f6328006a00c3681b53797374656d2e52756e74696d652e436865636b5769746e657373619164080061006c7566616a57c36a55c37e6a00c37e6a58527ac46a54c36a58c37c681253797374656d2e53746f726167652e476574616a59527ac46a59c30087630d006a59c36a53c39f64080061006c7566616a59c36a53c39c6425006a54c36a58c37c681553797374656d2e53746f726167652e44656c65746561622800616a54c36a58c36a59c36a53c3945272681253797374656d2e53746f726167652e50757461616a51c3c001149e630d006a52c3c001149e64080061006c7566616a56c36a51c37e6a5a527ac46a54c36a5ac37c681253797374656d2e53746f726167652e476574616a5b527ac46a5bc30087630d006a5bc36a53c39f64080061006c7566616a5bc36a53c39c6425006a54c36a5ac37c681553797374656d2e53746f726167652e44656c65746561622800616a54c36a5ac36a5bc36a53c3945272681253797374656d2e53746f726167652e50757461616a56c36a52c37e6a5c527ac46a54c36a5cc37c681253797374656d2e53746f726167652e476574616a5d527ac46a54c36a5cc36a5dc36a53c3935272681253797374656d2e53746f726167652e50757461087472616e736665726a51c36a52c36a53c354c176c9681553797374656d2e52756e74696d652e4e6f7469667961516c75660111c56b6a00527ac46a51527ac46a52527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a53527ac401016a54527ac40202206a55527ac46a52c3009f634f006a00c3681b53797374656d2e52756e74696d652e436865636b5769746e6573736191632a006a53c36a54c36a00c37e7c681253797374656d2e53746f726167652e476574616a52c39f64080061006c7566616a55c36a00c37e6a51c37e6a56527ac46a53c36a56c37c681253797374656d2e53746f726167652e476574616a57527ac46a57c300876426006a53c36a56c36a52c35272681253797374656d2e53746f726167652e50757461622800616a53c36a56c36a57c36a52c3935272681253797374656d2e53746f726167652e507574616107617070726f76656a00c36a51c36a52c354c176c9681553797374656d2e52756e74696d652e4e6f7469667961516c756656c56b6a00527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a51527ac401016a52527ac46a51c36a52c36a00c37e7c681253797374656d2e53746f726167652e476574616c756659c56b6a00527ac4006a52527ac46a00c3c06a53527ac4616a52c36a53c39f6445006a00c36a52c3c36a51527ac46a52c351936a52527ac46a51c3c0539e640700006c7566616a51c300c36a51c351c36a51c352c3527265140063bdff006c756662b6ff616161516c75660117c56b6a00527ac46a51527ac46a52527ac4681953797374656d2e53746f726167652e476574436f6e74657874616a53527ac401016a54527ac46a00c36a51c39c630b006a52c3009c64080061516c7566616a52c3009f6332006a00c3681b53797374656d2e52756e74696d652e436865636b5769746e6573736191630d006a51c3c001149e64080061006c7566616a54c36a00c37e6a55527ac46a53c36a55c37c681253797374656d2e53746f726167652e476574616a56527ac46a56c30087630d006a56c36a52c39f64080061006c7566616a56c36a52c39c6425006a53c36a55c37c681553797374656d2e53746f726167652e44656c65746561622800616a53c36a55c36a56c36a52c3945272681253797374656d2e53746f726167652e50757461616a54c36a51c37e6a57527ac46a53c36a57c37c681253797374656d2e53746f726167652e476574616a58527ac46a53c36a57c36a58c36a52c3935272681253797374656d2e53746f726167652e50757461087472616e736665726a00c36a51c36a52c354c176c9681553797374656d2e52756e74696d652e4e6f7469667961516c75665fc56b681953797374656d2e53746f726167652e476574436f6e74657874616a00527ac4144756c9dd829b2142883adbe1ae4f8689a1f673e96a51527ac40400e1f5056a52527ac40400e1f5056a53527ac401016a54527ac40c746f74616c5f737570706c796a55527ac46a00c36a55c37c681253797374656d2e53746f726167652e47657461009e640700006c7566616a53c36a52c3956a56527ac46a00c36a55c36a56c35272681253797374656d2e53746f726167652e507574616a00c36a54c36a51c37e6a56c35272681253797374656d2e53746f726167652e50757461087472616e73666572006a51c36a56c354c176c9681553797374656d2e52756e74696d652e4e6f7469667961516c75665ec56b6a00527ac46a51527ac46a51c36a00c3946a52527ac46a52c3c56a53527ac4006a54527ac46a00c36a55527ac461616a00c36a51c39f6433006a54c36a55c3936a56527ac46a56c36a53c36a54c37bc46a54c351936a54527ac46a55c36a54c3936a00527ac462c8ff6161616a53c36c7566' addr = Address.address_from_vm_code(code) contract_addr = addr.to_byte_array() abi = '{"functions":[{"name":"Main","parameters":[{"name":"op","type":""},{"name":"args","type":""}],"returntype":""},{"name":"init","parameters":[{"name":"","type":""}],"returntype":""},{"name":"transfer","parameters":[{"name":"acc_from","type":""},{"name":"acc_to","type":""},{"name":"value","type":""}],"returntype":""},{"name":"transfer_multi","parameters":[{"name":"arr","type":""}],"returntype":""},{"name":"balance_of","parameters":[{"name":"addr","type":""}],"returntype":""},{"name":"approve","parameters":[{"name":"owner","type":""},{"name":"spender","type":""},{"name":"amount","type":""}],"returntype":""},{"name":"transfer_from","parameters":[{"name":"spender","type":""},{"name":"from_acc","type":""},{"name":"to_acc","type":""},{"name":"amount","type":""}],"returntype":""},{"name":"allowance","parameters":[{"name":"owner","type":""},{"name":"spender","type":""}],"returntype":""},{"name":"decimal","parameters":[{"name":"","type":""}],"returntype":""},{"name":"symbol","parameters":[{"name":"","type":""}],"returntype":""},{"name":"total_supply","parameters":[{"name":"","type":""}],"returntype":""},{"name":"name","parameters":[{"name":"","type":""}],"returntype":""}]}' abi = json.loads(abi, object_hook=lambda d: namedtuple('X', d.keys())(*d.values())) abi_info = AbiInfo('0x' + addr.to_reverse_hex_str(), 'Main', abi.functions, []) acc1 = sdk.get_wallet_manager().get_account( 'ANH5bHrrt111XwNEnuPZj6u95Dd6u7G4D6', '1') acc2 = sdk.get_wallet_manager().get_account( 'AYvTfgEyYduk3zEKMDnZggWQqt9bkASNxJ', '060708') acc3 = sdk.get_wallet_manager().get_account( 'AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve', '060708') class TokenTest(TestCase): """ 测试Token合约的功能 """ def get_from_hex(self, res): """
#!/usr/bin/env python3 import json import unittest from ontology.smart_contract.neo_contract.abi.abi_info import AbiInfo str_abi = '{"hash":"0x362cb5608b3eca61d4846591ebb49688900fedd0","entrypoint":"Main","functions":' \ '[{"name":"Main","parameters":[{"name":"operation","type":"String"},{"name":"args",' \ '"type":"Array"}],"returntype":"Any"},{"name":"Hello","parameters":[{"name":"msg",' \ '"type":"String"}],"returntype":"Void"}],"events":[]}' dict_abi = json.loads(str_abi) abi_info = AbiInfo(dict_abi['hash'], dict_abi['entrypoint'], dict_abi['functions'], dict_abi['events']) func_name = 'Hello' class TestAbiInfo(unittest.TestCase): def test_init(self): self.assertTrue(isinstance(abi_info, AbiInfo)) def test_get_function(self): func = abi_info.get_function(func_name) self.assertEqual(func_name, func.name) def test_set_params_value(self): func = abi_info.get_function(func_name) func.set_params_value('Value') self.assertEqual('Value', func.parameters[0].value) def test_get_parameter(self):
class DemoClient(object): """ """ def __init__(self, rpc_addr: str, wallet_file: str, is_maker: bool, pwd, avm_file, abi_file): self.sdk = OntologySdk() self.sdk.rpc.set_address(rpc_addr) self.sdk.open_wallet(wallet_file) self.is_maker = is_maker # 可以查询一个合约存不存在,存在就可以让maker是True,而不必自己指定了 self.__pwd = pwd self.__get_code_from_avm(avm_file) self.__get_abi_from_file(abi_file) @staticmethod def is_transaction_success(txid): if len(txid) != 64: return False return True def start_game(self, acc_index): if not self.is_maker: return acc = self.get_account_by_index(acc_index) txid = self.deploy_contract(need_storage=True, name="sixsixsix", code_ver="1.0", author="tomzou", email="*****@*****.**", desp="demo", acc=acc, gas_limit=20200000, gas_price=500) if not self.is_transaction_success(txid): raise Exception(txid) return txid def get_account_by_index(self, acc_index): wm = self.sdk.get_wallet_manager() return wm.get_account( wm.get_wallet().get_account_by_index(acc_index).get_address(), self.__pwd[acc_index]) def deploy_contract(self, need_storage, name, code_ver, author, email, desp, acc, gas_limit, gas_price): tx = self.sdk.neo_vm().make_deploy_transaction( self.code, need_storage=need_storage, name=name, code_version=code_ver, author=author, email=email, desp=desp, payer=acc.get_address_base58(), gas_limit=gas_limit, gas_price=gas_price) self.sdk.sign_transaction(tx, acc) return self.sdk.get_rpc().send_raw_transaction(tx) def __get_code_from_avm(self, avm_file): f = open(avm_file) self.code = f.readline() code_addr_obj = Address.address_from_vm_code(self.code) self.code_addr = code_addr_obj.to_reverse_hex_str() self.contract_acc = code_addr_obj.to_base58() self.contract_addr = code_addr_obj.to_byte_array() f.close() def __get_abi_from_file(self, abi_file): f = open(abi_file) abi_str = f.readline() abi = json.loads(abi_str, object_hook=lambda d: namedtuple('X', d.keys()) (*d.values())) self.abi_info = AbiInfo("0x" + self.code_addr, "main", abi.functions, []) def luck_roll(self, amount, acc_index): """ 玩家通过本方法参与游戏 :param amount: :param acc_index: :return: """ self.join_game(amount, acc_index) if self.bet(amount, acc_index) is True: print('I win, you bitch') else: print('Go back and work, FOOL') def join_game(self, amount, acc_index): acc = self.get_account_by_index(acc_index) # 调用相应的函数,需写完合约再回头搞 func_join = self.abi_info.get_function("join") func_join.set_params_value(acc.get_address_base58(), amount) func_read_res = self.abi_info.get_function("is_game_ready") txid = self.sdk.neo_vm().send_transaction(self.contract_addr, acc, acc, 2000000, 500, func_join, False) print(txid) if not self.is_transaction_success(txid): raise Exception(txid) before = time.time() tx_info = self.sdk.get_rpc().get_smart_contract_event_by_txhash(txid) while tx_info == 'unknown transaction' or tx_info is None: tx_info = self.sdk.get_rpc().get_smart_contract_event_by_txhash( txid) print('cost %f seconds to confirm tx' % (time.time() - before)) try: notify_info = tx_info['Notify'][0]['States'] except Exception: raise Exception(tx_info) print(notify_info) if notify_info == '4e6f206d6f72652073656174': raise Exception("No more seat") elif notify_info == '6a6f696e207375636365737366756c6c79': # 等待游戏结束,不停滴向合约pull结果 while True: time.sleep(1) res = self.sdk.neo_vm().send_transaction( self.contract_addr, acc, acc, 2000000, 500, func_read_res, True) if res is True: print(res) break def bet(self, amount, acc_index): """ 人都坐好了,开赌! 掷出骰子并等待结果,返回输赢 :param amount: 需与join相同 :param acc_index: 使用钱包中第几个账户,需和join方法统一 :return: True代表胜利,False代表输了。。 """ acc = self.get_account_by_index(acc_index) tx = self.sdk.native_vm().asset().new_transfer_transaction( 'ont', acc.get_address_base58(), self.contract_acc, amount, acc.get_address_base58(), 2000000, 500) self.sdk.sign_transaction(tx, acc) txid = self.sdk.get_rpc().send_raw_transaction(tx) if not self.is_transaction_success(txid): raise Exception('Some thing wrong with tx:%s' % txid) func_get_amounts = self.abi_info.get_function('get_amounts') sum_amounts = self.sdk.neo_vm().send_transaction( self.contract_addr, acc, acc, 2000000, 500, func_get_amounts, True) contract_balance = self.sdk.get_rpc().get_balance(self.contract_acc) while sum_amounts > contract_balance: contract_balance = self.sdk.get_rpc().get_balance( self.contract_acc) time.sleep(0.5) # 直接开始游戏,获取随机数 func_roll_dice = self.abi_info.get_function('roll_dice') func_roll_dice.set_params_value(acc.get_address_base58()) txid = self.sdk.neo_vm().send_transaction(self.contract_addr, acc, acc, 2000000, 500, func_roll_dice, False) if not self.is_transaction_success(txid): raise Exception('Some thing wrong with tx:%s' % txid) before = time.time() tx_info = self.sdk.get_rpc().get_smart_contract_event_by_txhash(txid) while tx_info == 'unknown transaction' or tx_info is None: tx_info = self.sdk.get_rpc().get_smart_contract_event_by_txhash( txid) print('cost %f seconds to confirm tx' % (time.time() - before)) try: notify_info = tx_info['Notify'][0]['States'] except Exception: raise Exception(tx_info) if type(notify_info) is int: print('your game is done and your dice number is %d' % notify_info) else: raise Exception(bytes.fromhex(notify_info).decode()) func_get_res = self.abi_info.get_function('get_res') res = self.sdk.neo_vm().send_transaction(self.contract_addr, acc, acc, 2000000, 500, func_get_res, True) while res is False: res = self.sdk.neo_vm().send_transaction(self.contract_addr, acc, acc, 2000000, 500, func_get_res, True) time.sleep(0.5) if res == acc.get_address_base58(): return True else: return False