Ejemplo n.º 1
0
 def test_getTransactionCount(self, global_test_env):
     env = global_test_env
     node = env.get_rand_node()
     platon = Eth(node.web3)
     transaction_count = platon.getTransactionCount(env.account.get_rand_account()['address'])
     assert is_integer(transaction_count)
     assert transaction_count >= 0
Ejemplo n.º 2
0
def test_platon_gasPrice(global_running_env):
    node = global_running_env.get_rand_node()
    platon = Eth(node.web3)
    account = global_running_env.account
    from_address = account.account_with_money["address"]

    nCount = platon.getTransactionCount(Web3.toChecksumAddress(from_address))
    nonce = hex(nCount)
    gasprice = node.eth.gasPrice
    tx_hash = transaction_func(node=node, from_addr=from_address, to_addr=to_address, nonce=nonce, gasPrice=gasprice)
    assert len(tx_hash) == 32

    gasprice = node.eth.gasPrice * 2
    nCount = nCount + 1
    nonce = hex(nCount)
    tx_hash = transaction_func(node=node, from_addr=from_address, to_addr=to_address, nonce=nonce, gasPrice=gasprice)
    assert len(tx_hash) == 32

    gasprice = int(node.eth.gasPrice / 2)
    nCount = nCount + 1
    nonce = hex(nCount)

    status = 0
    try:
        transaction_func(node=node, from_addr=from_address, to_addr=to_address, nonce=nonce, gasPrice=gasprice)
        status = 1
    except Exception as e:
        print("\nUse less than the recommended gasprice:{}, nonce:{}, Send transaction failed,error message:{}".format(gasprice, nonce, e))
    assert status == 0
Ejemplo n.º 3
0
def test_platon_estimateGas(global_running_env):
    node = global_running_env.get_rand_node()
    account = global_running_env.account
    platon = Eth(node.web3)
    address = account.account_with_money["address"]

    nCount = platon.getTransactionCount(Web3.toChecksumAddress(address))
    nonce = hex(nCount)
    estimateGas = transaction_func(node=node, from_addr=address, to_addr=to_address, nonce=nonce, gas='')
    gas = estimateGas

    tx_hash = transaction_func(node=node, from_addr=address, to_addr=to_address, nonce=nonce, gas=gas)
    assert len(tx_hash) == 32
    nCount = nCount + 1
    nonce = hex(nCount)

    gas = int(estimateGas * 2)
    tx_hash = transaction_func(node=node, from_addr=address, to_addr=to_address, nonce=nonce, gas=gas)
    assert len(tx_hash) == 32
    nCount = nCount + 1
    nonce = hex(nCount)

    gas = int(estimateGas / 2)
    status = 0
    try:
        transaction_func(node=node, from_addr=address, to_addr=to_address, nonce=nonce, gas=gas)
        status = 1
    except Exception as e:
        print("\nUse less gas than expected:【{}】,Send transaction failed,error message:{}".format(gas, e))
    assert status == 0
Ejemplo n.º 4
0
def test_platon_GetBlock(global_running_env):
    node = global_running_env.get_rand_node()
    account = global_running_env.account
    platon = Eth(node.web3)
    address = account.account_with_money["address"]
    nCount = platon.getTransactionCount(Web3.toChecksumAddress(address))
    nonce = hex(nCount)

    log.info(f'node: {node.host} {node.p2p_port}, address: {address}')

    gasprice = node.eth.gasPrice
    # send transaction
    if g_txHash is None:
        tx_hash = transaction_func(node=node,
                                   from_addr=address,
                                   to_addr=to_address,
                                   nonce=nonce,
                                   gasPrice=gasprice)
    else:
        tx_hash = g_txHash

    assert len(tx_hash) == 32
    tx_hash = HexBytes(tx_hash).hex()
    print("\ntransaction hash:{}".format(tx_hash))
    # Waiting for transaction on the chain
    result = node.eth.waitForTransactionReceipt(tx_hash)
    assert None != result
    # get block info by transaction receipt
    blockHash = result["blockHash"]
    blockNumber = result["blockNumber"]
    assert len(blockHash) == 32
    blockHash = HexBytes(blockHash).hex()
    # get block by blockHash
    # fullTx:Flase
    blockInfo = node.eth.getBlock(blockHash, False)
    blockHash = blockInfo['hash']
    blockNumber = blockInfo['number']
    assert len(blockHash) == 32
    assert blockNumber > 0
    fullTransaction = blockInfo["transactions"]
    assert len(fullTransaction) > 0
    # fullTx:True
    blockInfo = node.eth.getBlock(blockHash, True)
    blockHash = blockInfo['hash']
    assert len(blockHash) == 32
    fullTransaction = blockInfo["transactions"]
    assert len(fullTransaction) > 0
    # get block by blockNumber
    # fullTx:Flase
    blockInfo = node.eth.getBlock(blockNumber, False)
    blockHash = blockInfo['hash']
    assert len(blockHash) == 32
    fullTransaction = blockInfo["transactions"]
    assert len(fullTransaction) > 0
    # fullTx:True
    blockInfo = node.eth.getBlock(blockNumber, True)
    blockHash = blockInfo['hash']
    assert len(blockHash) == 32
    fullTransaction = blockInfo["transactions"]
    assert len(fullTransaction) > 0
Ejemplo n.º 5
0
    def sendTransaction(self,
                        connect,
                        data,
                        from_address,
                        to_address,
                        gasPrice,
                        gas,
                        value,
                        check_address=True):
        platon = Eth(connect)
        account = self.accounts[from_address]
        nonce = platon.getTransactionCount(from_address)
        transaction_dict = {
            "to": to_address,
            "gasPrice": gasPrice,
            "gas": gas,
            "nonce": nonce,
            "data": data,
            "chainId": self.chain_id,
            "value": value,
        }

        signedTransactionDict = platon.account.signTransaction(
            transaction_dict, account['prikey'])

        data = signedTransactionDict.rawTransaction
        result = HexBytes(platon.sendRawTransaction(data)).hex()
        # log.debug("result:::::::{}".format(result))
        res = platon.waitForTransactionReceipt(result)
        account['nonce'] = nonce + 1
        self.accounts[from_address] = account
        return res
Ejemplo n.º 6
0
def test_platon_estimateGas(global_running_env):
    node = global_running_env.get_rand_node()
    account = global_running_env.account
    platon = Eth(node.web3)
    address = account.account_with_money["address"]

    nCount = platon.getTransactionCount(Web3.toChecksumAddress(address))
    nonce = hex(nCount)
    # 获取交易的预估值
    estimateGas = transaction_func(node=node,
                                   from_addr=address,
                                   to_addr=to_address,
                                   nonce=nonce,
                                   gas='')
    gas = estimateGas
    print("\n交易预估gas:{}".format(gas))

    # 发送交易
    tx_hash = transaction_func(node=node,
                               from_addr=address,
                               to_addr=to_address,
                               nonce=nonce,
                               gas=gas)
    assert len(tx_hash) == 32
    print("\n使用预估的交易gas:【{}】,发送交易成功,交易hash:【{}】".format(
        gas,
        HexBytes(tx_hash).hex()))
    nCount = nCount + 1
    nonce = hex(nCount)

    gas = int(estimateGas * 2)
    tx_hash = transaction_func(node=node,
                               from_addr=address,
                               to_addr=to_address,
                               nonce=nonce,
                               gas=gas)
    assert len(tx_hash) == 32
    print("\n使用大于预估的交易gas:【{}】,发送交易成功,交易hash:【{}】".format(
        gas,
        HexBytes(tx_hash).hex()))
    nCount = nCount + 1
    nonce = hex(nCount)

    gas = int(estimateGas / 2)
    # 异常测试场景
    status = 0
    try:
        transaction_func(node=node,
                         from_addr=address,
                         to_addr=to_address,
                         nonce=nonce,
                         gas=gas)
        status = 1
    except Exception as e:
        print("\n使用小于预估的交易gas:【{}】,发送交易失败,error message:{}".format(gas, e))
    assert status == 0
Ejemplo n.º 7
0
def batch_send_transfer(txfile, config):
    # 交易文件列表
    if txfile == "":
        print("-f/--txfile is null, please input.")
        exit(1)

    # 发送交易的节点配置信息
    if config == "":
        print("-c/--config is null, please input.")
        exit(1)

    try:
        # 获取节点 url
        with open(config, 'r') as load_f:
            config_info = json.load(load_f)
            url = config_info['nodeAddress'] + ":" + config_info['nodeRpcPort']

        # 获取交易列表
        transaction_list_raw = read_csv(txfile)
        transaction_list = []
        for one_transaction in transaction_list_raw:
            transaction_list.append(transaction_str_to_int(one_transaction))

        if len(transaction_list) == 0 :
            print("have not transaction.")
            exit(1)
        w3 = Web3(HTTPProvider(url))
        platon = Eth(w3)
        # 获取当前nonce
        curr_nonce = platon.getTransactionCount(Web3.toChecksumAddress(transaction_list[0]["from"]))

        # 发送交易
        print('\nstart to send transfer transaction, please wait...\n')
        for one_transaction in transaction_list:
            if curr_nonce > int(one_transaction["nonce"]):
                continue
            transfer_send(platon, one_transaction["rawTransaction"])
            sleep(1)

    except Exception as e:
        print('{} {}'.format('exception: ', e))
        print('batch send transfer transaction failure!!!')
        sys.exit(1)
    else:
        print('batch send transfer transaction SUCCESS.')
        end = datetime.datetime.now()
        print("end:{}".format(end))
        print("总共消耗时间:{}s".format((end - start).seconds))
        sys.exit(0)
Ejemplo n.º 8
0
def test_platon_gasPrice(global_running_env):
    node = global_running_env.get_rand_node()
    platon = Eth(node.web3)
    account = global_running_env.account
    from_address = account.account_with_money["address"]

    nCount = platon.getTransactionCount(Web3.toChecksumAddress(from_address))
    nonce = hex(nCount)
    gasprice = node.eth.gasPrice
    tx_hash = transaction_func(node=node,
                               from_addr=from_address,
                               to_addr=to_address,
                               nonce=nonce,
                               gasPrice=gasprice)
    assert len(tx_hash) == 32
    print("\n使用建议的交易gasprice:{},发送交易成功,交易hash:{}".format(
        gasprice,
        HexBytes(tx_hash).hex()))

    gasprice = node.eth.gasPrice * 2
    nCount = nCount + 1
    nonce = hex(nCount)
    tx_hash = transaction_func(node=node,
                               from_addr=from_address,
                               to_addr=to_address,
                               nonce=nonce,
                               gasPrice=gasprice)
    assert len(tx_hash) == 32
    print("\n使用大于建议的交易gasprice,发送交易成功,交易hash:{},  gasprice:{}".format(
        HexBytes(tx_hash).hex(), gasprice))

    gasprice = int(node.eth.gasPrice / 2)
    nCount = nCount + 1
    nonce = hex(nCount)

    # 异常测试场景
    status = 0
    try:
        transaction_func(node=node,
                         from_addr=from_address,
                         to_addr=to_address,
                         nonce=nonce,
                         gasPrice=gasprice)
        status = 1
    except Exception as e:
        print(
            "\n使用小于建议的交易gasprice:{}, nonce:{}, 发送交易失败,error message:{}".format(
                gasprice, nonce, e))
    assert status == 0
Ejemplo n.º 9
0
    def sendTransaction(self,
                        connect,
                        data,
                        from_address,
                        to_address,
                        gasPrice,
                        gas,
                        value,
                        check_address=True):
        platon = Eth(connect)

        account = self.accounts[from_address]
        if check_address:
            to_address = Web3.toChecksumAddress(to_address)
        tmp_from_address = Web3.toChecksumAddress(from_address)
        nonce = platon.getTransactionCount(tmp_from_address)

        # if nonce < account['nonce']:
        #     nonce = account['nonce']

        transaction_dict = {
            "to": to_address,
            "gasPrice": gasPrice,
            "gas": gas,
            "nonce": nonce,
            "data": data,
            "chainId": self.chain_id,
            "value": value,
            'from': tmp_from_address,
        }

        # log.debug("account['prikey']:::::::{}".format(account['prikey']))

        signedTransactionDict = platon.account.signTransaction(
            transaction_dict, account['prikey'])

        # log.debug("signedTransactionDict:::::::{},nonce::::::::::{}".format(signedTransactionDict, nonce))

        data = signedTransactionDict.rawTransaction
        result = HexBytes(platon.sendRawTransaction(data)).hex()
        # log.debug("result:::::::{}".format(result))
        res = platon.waitForTransactionReceipt(result)
        account['nonce'] = nonce + 1
        self.accounts[from_address] = account

        return res
Ejemplo n.º 10
0
def test_personal_signTransaction(global_running_env):
    node = global_running_env.get_rand_node()
    account = global_running_env.account
    platon = Eth(node.web3)
    addr = account.account_with_money["address"]

    nonce = hex(platon.getTransactionCount(Web3.toChecksumAddress(addr)))
    transaction_dict = {
        "from": Web3.toChecksumAddress(addr),
        "to": Web3.toChecksumAddress(to_address),
        "value": "0x10000000000000",
        "data": "0x11",
        "gasPrice": "0x8250de00",
        "gas": "0x6fffffff",
        "nonce": nonce,
    }
    ret = node.personal.signTransaction(transaction_dict, password)
    assert ret is not None
Ejemplo n.º 11
0
    def test_platon_sendTransaction_with_nonce(self, unlocked_account):

        platon = Eth(unlocked_account['node'].web3)
        txn_params = {
            'from': unlocked_account['address'],
            'to': unlocked_account['address'],
            'value': 1,
            'gas': 21000,
            # Increased gas price to ensure transaction hash different from other tests
            'gasPrice': platon.gasPrice * 2,
            'nonce': platon.getTransactionCount(unlocked_account['address']),
        }
        txn_hash = platon.sendTransaction(txn_params)
        txn = platon.getTransaction(txn_hash)

        assert is_same_address(txn['from'], txn_params['from'])
        assert is_same_address(txn['to'], txn_params['to'])
        assert txn['value'] == 1
        assert txn['gas'] == 21000
        assert txn['gasPrice'] == txn_params['gasPrice']
Ejemplo n.º 12
0
class Ppos:
    def __init__(self, url, address, password, privatekey=conf.PRIVATE_KEY):
        self.web3 = connect_web3(url)
        if not self.web3.isConnected():
            raise Exception("node connection failed")
        self.eth = Eth(self.web3)
        self.address = Web3.toChecksumAddress(address)
        self.privatekey = privatekey
        self.gasPrice = "0x8250de00"
        self.gas = "0x6fffffff"

    def get_result(self, tx_hash, func_name):
        result = self.eth.waitForTransactionReceipt(tx_hash)
        print(result)
        """查看eventData"""
        data = result['logs'][0]['data']
        if data[:2] == '0x':
            data = data[2:]
        # print(data)
        data_bytes = rlp.decode(bytes.fromhex(data))[0]
        event_data = bytes.decode(data_bytes)
        return func_name, event_data

    def send_raw_transaction(self, data, from_address, to_address, gasPrice,
                             gas, value):
        nonce = self.eth.getTransactionCount(from_address)
        if value > 0:
            transaction_dict = {
                "to": to_address,
                "gasPrice": gasPrice,
                "gas": gas,
                "nonce": nonce,
                "data": data,
                "chainId": 102,
                "value": self.web3.toWei(value, "ether"),
            }
        else:
            transaction_dict = {
                "to": to_address,
                "gasPrice": gasPrice,
                "gas": gas,
                "nonce": nonce,
                "data": data,
                "chainId": 102
            }
        signedTransactionDict = self.eth.account.signTransaction(
            transaction_dict, self.privatekey)
        data = signedTransactionDict.rawTransaction
        result = HexBytes(self.eth.sendRawTransaction(data)).hex()
        return result

    def staking(self,
                typ,
                benifitAddress,
                nodeId,
                externalId,
                nodeName,
                website,
                details,
                amount,
                programVersion,
                from_address=None,
                gasPrice=None,
                gas=None):
        '''
        Description :发起质押
        :param typ:  uint16(2bytes)
        :param benifitAddress:  20bytes
        :param nodeId: 64bytes
        :param externalId:  string
        :param nodeName: string
        :param website: string
        :param details: string
        :param amount: *big.Int(bytes)
        :param programVersion: uint32
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
            Ret: bool
            data:[]
            ErrMsg: string
        '''
        if benifitAddress[:2] == '0x':
            benifitAddress = benifitAddress[2:]
        data = HexBytes(
            rlp.encode([
                rlp.encode(int(1000)),
                rlp.encode(int(typ)),
                rlp.encode(bytes.fromhex(benifitAddress)),
                rlp.encode(bytes.fromhex(nodeId)),
                rlp.encode(externalId),
                rlp.encode(nodeName),
                rlp.encode(website),
                rlp.encode(details),
                rlp.encode(self.web3.toWei(amount, 'ether')),
                rlp.encode(programVersion)
            ])).hex()
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data, from_address, to_address,
                                           gasPrice, gas, amount)
        print(result)
        return self.get_result(result, self.staking.__name__)

    def updateStakingInfo(self,
                          benifitAddress,
                          nodeId,
                          externalId,
                          nodeName,
                          website,
                          details,
                          from_address=None,
                          gasPrice=None,
                          gas=None):
        '''
        Description : 修改质押信息
        :param benifitAddress: 20bytes
        :param nodeId:  64bytes
        :param externalId:  string
        :param nodeName:  string
        :param website: string
        :param details: string
        :param from_address: string
        :param gasPrice:
        :param gas:
        :return:
            Ret: bool
            data:[]
            ErrMsg: string

        '''
        if benifitAddress[:2] == '0x':
            benifitAddress = benifitAddress[2:]
        data = HexBytes(
            rlp.encode([
                rlp.encode(int(1001)),
                rlp.encode(bytes.fromhex(benifitAddress)),
                rlp.encode(bytes.fromhex(nodeId)),
                rlp.encode(externalId),
                rlp.encode(nodeName),
                rlp.encode(website),
                rlp.encode(details)
            ])).hex()
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.updateStakingInfo.__name__)

    def addStaking(self,
                   nodeId,
                   typ,
                   amount,
                   from_address=None,
                   gasPrice=None,
                   gas=None):
        '''
        Description : 增持质押
        :param nodeId: 64bytes
        :param typ: uint16(2bytes)
        :param amount:  *big.Int(bytes)
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
            Ret: bool
            data:[]
            ErrMsg: string
        '''
        data = HexBytes(
            rlp.encode([
                rlp.encode(int(1002)),
                rlp.encode(bytes.fromhex(nodeId)),
                rlp.encode(int(typ)),
                rlp.encode(self.web3.toWei(amount, 'ether'))
            ])).hex()
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.addStaking.__name__)

    def unStaking(self, nodeId, from_address=None, gasPrice=None, gas=None):
        '''
        Description : 撤销质押
        :param nodeId: 64bytes
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
            Ret: bool
            data:[]
            ErrMsg: string
        '''
        data = rlp.encode(
            [rlp.encode(int(1003)),
             rlp.encode(bytes.fromhex(nodeId))])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.unStaking.__name__)

    def delegate(self,
                 typ,
                 nodeId,
                 amount,
                 from_address=None,
                 gasPrice=None,
                 gas=None):
        '''
        Description :发起委托
        :param typ: uint16(2bytes)
        :param nodeId: 64bytes
        :param amount:  *big.Int(bytes)
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
            Ret: bool
            data:[]
            ErrMsg: string
        '''
        data = rlp.encode([
            rlp.encode(int(1004)),
            rlp.encode(int(typ)),
            rlp.encode(bytes.fromhex(nodeId)),
            rlp.encode(self.web3.toWei(amount, 'ether'))
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.delegate.__name__)

    def unDelegate(self,
                   stakingBlockNum,
                   nodeId,
                   amount,
                   from_address=None,
                   gasPrice=None,
                   gas=None):
        '''
        Description :减持/撤销委托(全部减持就是撤销)
        :param stakingBlockNum: uint64(8bytes)
        :param nodeId: 64bytes
        :param amount: *big.Int(bytes)
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(1005)),
            rlp.encode(int(stakingBlockNum)),
            rlp.encode(bytes.fromhex(nodeId)),
            rlp.encode(self.web3.toWei(amount, 'ether'))
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000002"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.unDelegate.__name__)

    def getVerifierList(self):
        '''
        @GetVerifierList: 查询当前结算周期的验证人队列
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            'NodeId': 被质押的节点Id(也叫候选人的节点Id)
            StakingAddress: 发起质押时使用的账户(后续操作质押信息只能用这个账户,撤销质押时,von会被退回该账户或者该账户的锁仓信息中)
            BenefitAddress: 用于接受出块奖励和质押奖励的收益账户
            StakingTxIndex: 发起质押时的交易索引
            ProcessVersion: 被质押节点的PlatON进程的真实版本号(获取版本号的接口由治理提供)
            StakingBlockNum: 发起质押时的区块高度
            Shares: 当前候选人总共质押加被委托的von数目
            ExternalId: 外部Id(有长度限制,给第三方拉取节点描述的Id)
            NodeName: 被质押节点的名称(有长度限制,表示该节点的名称)
            Website: 节点的第三方主页(有长度限制,表示该节点的主页)
            Details: 节点的描述(有长度限制,表示该节点的描述)
            ValidatorTerm: 验证人的任期(在结算周期的101个验证人快照中永远是0,只有备选为下一共识轮验证人时才会被变更,刚被选出来时也是0,继续留任时则+1)
        '''
        data = rlp.encode([rlp.encode(int(1100))])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = (self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        }))
        recive = str(recive, encoding="utf8")
        recive = recive.replace('\\', '').replace('"[', '[').replace(']"', ']')
        recive = json.loads(recive)
        return recive

    def getValidatorList(self):
        '''
           @GetVerifierList: 查询当前共识周期的验证人列表
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            'NodeId': 被质押的节点Id(也叫候选人的节点Id)
            StakingAddress: 发起质押时使用的账户(后续操作质押信息只能用这个账户,撤销质押时,von会被退回该账户或者该账户的锁仓信息中)
            BenefitAddress: 用于接受出块奖励和质押奖励的收益账户
            StakingTxIndex: 发起质押时的交易索引
            ProcessVersion: 被质押节点的PlatON进程的真实版本号(获取版本号的接口由治理提供)
            StakingBlockNum: 发起质押时的区块高度
            Shares: 当前候选人总共质押加被委托的von数目
            ExternalId: 外部Id(有长度限制,给第三方拉取节点描述的Id)
            NodeName: 被质押节点的名称(有长度限制,表示该节点的名称)
            Website: 节点的第三方主页(有长度限制,表示该节点的主页)
            Details: 节点的描述(有长度限制,表示该节点的描述)
            ValidatorTerm: 验证人的任期(在结算周期的101个验证人快照中永远是0,只有备选为下一共识轮验证人时才会被变更,刚被选出来时也是0,继续留任时则+1)
        '''
        data = rlp.encode([rlp.encode(int(1101))])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="utf8")
        recive = recive.replace('\\', '').replace('"[', '[').replace(']"', ']')
        recive = json.loads(recive)
        return recive

    def getCandidateList(self):
        '''
        @GetVerifierList: 查询所有实时的候选人列表
        @param {type} @@@@
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            'NodeId': 被质押的节点Id(也叫候选人的节点Id)
            StakingAddress: 发起质押时使用的账户(后续操作质押信息只能用这个账户,撤销质押时,von会被退回该账户或者该账户的锁仓信息中)
            BenefitAddress: 用于接受出块奖励和质押奖励的收益账户
            StakingTxIndex: 发起质押时的交易索引
            ProcessVersion: 被质押节点的PlatON进程的真实版本号(获取版本号的接口由治理提供)
            Status: 候选人的状态(0: 节点可用; 1: 节点不可用; 2: 节点出块率低; 4: 节点的von不足最低质押门槛; 8:节点被举报双签)
            StakingEpoch: 当前变更质押金额时的结算周期
            StakingBlockNum: 发起质押时的区块高度
            Shares: 当前候选人总共质押加被委托的von数目
            Released: 发起质押账户的自由金额的锁定期质押的von
            ReleasedHes: 发起质押账户的自由金额的犹豫期质押的von
            RestrictingPlan: 发起质押账户的锁仓金额的锁定期质押的von
            RestrictingPlanHes: 发起质押账户的锁仓金额的犹豫期质押的von
            ExternalId: 外部Id(有长度限制,给第三方拉取节点描述的Id)
            NodeName: 被质押节点的名称(有长度限制,表示该节点的名称)
            Website: 节点的第三方主页(有长度限制,表示该节点的主页)
            Details: 节点的描述(有长度限制,表示该节点的描述)
        '''
        data = rlp.encode([rlp.encode(int(1102))])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="utf8")
        recive = recive.replace('\\', '').replace('"[', '[').replace(']"', ']')
        recive = json.loads(recive)
        return recive

    def getDelegateListByAddr(self, addr):
        '''
        @getDelegateListByAddr: 查询当前账户地址所委托的节点的NodeID和质押Id
        @param {type} @@@@
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            Addr: 验证人节点的地址
            NodeId: 验证人的节点Id
            StakingBlockNum: 发起质押时的区块高度
        '''
        if addr[:2] == '0x':
            addr = addr[2:]
        data = rlp.encode(
            [rlp.encode(int(1103)),
             rlp.encode(bytes.fromhex(addr))])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="utf8")
        recive = recive.replace('"[', '[').replace(']"', ']')
        recive = json.loads(recive)
        return recive

    def getDelegateInfo(self, stakingBlockNum, delAddr, nodeId):
        '''
        @getDelegateInfo: 查询当前单个委托信息
        @param {type} @@@@
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            Addr: 验证人节点的地址
            NodeId: 验证人的节点Id
            StakingBlockNum: 发起质押时的区块高度
            DelegateEpoch: 最近一次对该候选人发起的委托时的结算周期
            Released: 发起委托账户的自由金额的锁定期委托的von
            ReleasedHes: 发起委托账户的自由金额的犹豫期委托的von
            RestrictingPlan: 发起委托账户的锁仓金额的锁定期委托的von
            RestrictingPlanHes :发起委托账户的锁仓金额的犹豫期委托的von
        '''
        if delAddr[:2] == '0x':
            delAddr = delAddr[2:]
        data = rlp.encode([
            rlp.encode(int(1104)),
            rlp.encode(stakingBlockNum),
            rlp.encode(bytes.fromhex(delAddr)),
            rlp.encode(bytes.fromhex(nodeId))
        ])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="utf8")
        recive = json.loads(recive)
        return recive

    def getCandidateInfo(self, nodeId):
        '''
        @getDelegateInfo: 查询当前节点的质押信息
        @param {type} @@@@
        @return:
            Ret: bool 操作结果
            ErrMsg: string 错误信息
            []:列表
            NodeId: 被质押的节点Id(也叫候选人的节点Id)
            StakingAddress: 发起质押时使用的账户(后续操作质押信息只能用这个账户,撤销质押时,von会被退回该账户或者该账户的锁仓信息中)
            BenefitAddress: 用于接受出块奖励和质押奖励的收益账户
            StakingTxIndex: 发起质押时的交易索引
            ProcessVersion: 被质押节点的PlatON进程的真实版本号(获取版本号的接口由治理提供)
            Status: 候选人的状态(0: 节点可用; 1: 节点不可用; 2: 节点出块率低; 4: 节点的von不足最低质押门槛; 8:节点被举报双签)
            StakingEpoch :发起委托账户的锁仓金额的犹豫期委托的von
            StakingBlockNum :发起质押时的区块高度
            Shares: 当前候选人总共质押加被委托的von数目
            Released: 发起质押账户的自由金额的锁定期质押的von
            ReleasedHes: 发起质押账户的自由金额的犹豫期质押的von
            RestrictingPlan: 发起质押账户的锁仓金额的锁定期质押的von
            RestrictingPlanHes: 发起质押账户的锁仓金额的犹豫期质押的von
            ExternalId: 外部Id(有长度限制,给第三方拉取节点描述的Id)
            NodeName: 被质押节点的名称(有长度限制,表示该节点的名称)
            Website: 节点的第三方主页(有长度限制,表示该节点的主页)
            Details: 节点的描述(有长度限制,表示该节点的描述)
        '''
        data = rlp.encode(
            [rlp.encode(int(1105)),
             rlp.encode(bytes.fromhex(nodeId))])
        to_address = "0x1000000000000000000000000000000000000002"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="utf8")
        recive = recive.replace('\\', '').replace('"{', '{').replace('}"', '}')
        recive = json.loads(recive)
        return recive

#################################治理###############################

    def submitText(self,
                   verifier,
                   githubID,
                   topic,
                   desc,
                   url,
                   endVotingBlock,
                   from_address=None,
                   gasPrice=None,
                   gas=None):
        '''
        提交文本提案
        :param verifier: 64bytes
        :param githubID: string
        :param topic: string
        :param desc: string
        :param url: string
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(2000)),
            rlp.encode(bytes.fromhex(verifier)),
            rlp.encode(githubID),
            rlp.encode(topic),
            rlp.encode(desc),
            rlp.encode(url),
            rlp.encode(endVotingBlock)
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.submitText.__name__)

    def submitVersion(self,
                      verifier,
                      githubID,
                      topic,
                      desc,
                      url,
                      newVersion,
                      endVotingBlock,
                      activeBlock,
                      from_address=None,
                      gasPrice=None,
                      gas=None):
        '''
        提交升级提案
        :param verifier: 64bytes
        :param githubID: string
        :param topic: string
        :param desc: string
        :param url: string
        :param newVersion: uint
        :param endVotingBlock: uint64
        :param activeBlock: uint64
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(2001)),
            rlp.encode(bytes.fromhex(verifier)),
            rlp.encode(githubID),
            rlp.encode(topic),
            rlp.encode(desc),
            rlp.encode(url),
            rlp.encode(int(newVersion)),
            rlp.encode(int(endVotingBlock)),
            rlp.encode(int(activeBlock))
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.submitVersion.__name__)

    def submitParam(self,
                    verifier,
                    githubID,
                    topic,
                    desc,
                    url,
                    endVotingBlock,
                    paramName,
                    currentValue,
                    newValue,
                    from_address=None,
                    gasPrice=None,
                    gas=None):
        '''
        提交参数提案
        :param verifier: 64bytes
        :param githubID: string
        :param topic: string
        :param desc: string
        :param url: string
        :param endVotingBlock: uint64
        :param paramName:string
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(2002)),
            rlp.encode(bytes.fromhex(verifier)),
            rlp.encode(githubID),
            rlp.encode(topic),
            rlp.encode(desc),
            rlp.encode(url),
            rlp.encode(int(endVotingBlock)),
            rlp.encode(paramName),
            rlp.encode(str(currentValue)),
            rlp.encode(str(newValue))
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.submitParam.__name__)

    def vote(self,
             verifier,
             proposalID,
             option,
             from_address=None,
             gasPrice=None,
             gas=None):
        '''
        给提案投票
        :param verifier: 64bytes
        :param proposalID: common.Hash
        :param option: VoteOption
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(2003)),
            rlp.encode(bytes.fromhex(verifier)),
            rlp.encode(proposalID),
            rlp.encode(option)
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.vote.__name__)

    def declareVersion(self,
                       activeNode,
                       version,
                       from_address=None,
                       gasPrice=None,
                       gas=None):
        '''
        版本声明
        :param activeNode: 64bytes
        :param version: uint
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([
            rlp.encode(int(2004)),
            rlp.encode(bytes.fromhex(activeNode)),
            rlp.encode(int(version))
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.declareVersion.__name__)

    def getProposal(self,
                    proposalID,
                    from_address=None,
                    gasPrice=None,
                    gas=None):
        '''
        查询提案
        :param proposalID: common.Hash
        :return:
        '''
        data = rlp.encode([rlp.encode(int(2100)), rlp.encode(proposalID)])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        # print(result)
        return self.get_result(result, self.getProposal.__name__)

    def getTallyResult(self,
                       proposalID,
                       from_address=None,
                       gasPrice=None,
                       gas=None):
        '''
        查询提案结果
        :param proposalID: common.Hash
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([rlp.encode(int(2101)), rlp.encode(str(proposalID))])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        print(result)
        return self.get_result(result, self.getTallyResult.__name__)

    def listProposal(self, from_address=None, gasPrice=None, gas=None):
        '''
        查询提案列表
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data = rlp.encode([rlp.encode(int(2102))])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000005"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.listProposal.__name__)

############################举报惩罚###############################################################

    def ReportMutiSign(self, data, from_address=None, gasPrice=None, gas=None):
        '''
        举报双签
        :param data: string
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        data_ = rlp.encode([rlp.encode(data)])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000004"
        result = self.send_raw_transaction(data_,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.ReportMutiSign.__name__)

    def CheckMutiSign(self,
                      typ,
                      addr,
                      blockNumber,
                      from_address=None,
                      gasPrice=None,
                      gas=None):
        '''
        查询节点是否已被举报过多签
        :param typ: uint8(1byte)
        :param addr: 20bytes
        :param blockNumber:
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        if addr[:2] == '0x':
            addr = addr[2:]
        data = rlp.encode([
            rlp.encode(int(3001)),
            rlp.encode(int(typ)),
            rlp.encode(str(addr)),
            rlp.encode(blockNumber)
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000004"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.CheckMutiSign.__name__)


#######################################锁仓###############################################

    def CreateRestrictingPlan(self,
                              account,
                              plan,
                              from_address=None,
                              gasPrice=None,
                              gas=None):
        '''
        创建锁仓计划
        :param account: 20bytes
        :param plan: []RestrictingPlan
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        if account[:2] == '0x':
            account = account[2:]
        plan_list = []
        for dict_ in plan:
            v = [rlp.encode(dict_[k]) for k in dict_]
            # print(v)
            plan_list.append(v)
        # print(rlp.encode(plan_list))
        data = rlp.encode([
            rlp.encode(int(4000)),
            rlp.encode(bytes.fromhex(account)),
            rlp.encode(plan_list)
        ])
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            gas = self.gas
        to_address = "0x1000000000000000000000000000000000000001"
        result = self.send_raw_transaction(data,
                                           from_address,
                                           to_address,
                                           gasPrice,
                                           gas,
                                           value=0)
        return self.get_result(result, self.CreateRestrictingPlan.__name__)

    def GetRestrictingInfo(self, account):
        '''
        获取锁仓信息
        :param account: 20bytes
        :param from_address:
        :param gasPrice:
        :param gas:
        :return:
        '''
        if account[:2] == '0x':
            account = account[2:]
        data = rlp.encode(
            [rlp.encode(int(4100)),
             rlp.encode(bytes.fromhex(account))])
        to_address = "0x1000000000000000000000000000000000000001"
        recive = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        recive = str(recive, encoding="ISO-8859-1")
        recive = recive[10:]
        recive = eval(recive)
        # print(recive)
        return recive
Ejemplo n.º 13
0
def signed_batch_transfer(fromprivate, tolist, nonce, amount, config):
    # 发交易钱包文件
    if fromprivate == "":
        print("-f/--fromprivate is null, please input.")
        exit(1)

    # 接收交易地址列表文件
    if tolist == "":
        print("-t/--tolist is null, please input.")
        exit(1)
    else:
        if not tolist.endswith(".csv"):
            raise Exception("File format error")

    # 转账金额
    if amount == "":
        print("-a/--amount is null, please input.")
        exit(1)

    # 发送交易的节点配置信息
    if config == "":
        print("-c/--config is null, please input.")
        exit(1)

    try:
        # 获取转出地址
        address_prikey_list = read_csv(fromprivate)
        if len(address_prikey_list) == 0:
            print(
                "The wallet private key file that sent the transaction is empty, please check!"
            )
            exit(1)
        from_address = address_prikey_list[0]["address"]
        from_prikey = address_prikey_list[0]["private"]
        # 获取节点 url
        with open(config, 'r') as load_f:
            config_info = json.load(load_f)
            url = config_info['nodeAddress'] + ":" + config_info['nodeRpcPort']
            chainId = int(config_info['chainId'])
        # 和节点建立连接
        w3 = Web3(HTTPProvider(url))
        platon = Eth(w3)
        gasPrice = platon.gasPrice

        # 转账金额(LAT转换成VON)
        value = w3.toWei(amount, "ether")
        print("transfer amount:{}VON".format(value))

        if nonce == 0:
            nonce = platon.getTransactionCount(
                Web3.toChecksumAddress(from_address))

        # 获取转账 to 钱包名称
        all_transaction = []
        rows = read_csv(tolist)
        for row in rows:
            if 'address' in row:
                to_address = row["address"]
            else:
                raise Exception(
                    "The address field does not exist in the address file!")

            one_transaction_data = transfer_sign(from_address, to_address,
                                                 value, nonce, gasPrice,
                                                 from_prikey, chainId)
            all_transaction.append(one_transaction_data)
            nonce += 1

        # 生成 csv 文件
        #stamp = get_time_stamp()
        suffix = os.path.basename(tolist)
        transaction_file_name = "signed_batch_transfer_" + suffix
        write_csv(transaction_file_name, all_transaction)

    except Exception as e:
        print('{} {}'.format('exception: ', e))
        print('generate unsigned transaction file failure!!!')
        sys.exit(1)

    else:
        csvPath = os.getcwd() + "\\" + transaction_file_name
        print('{}{} {}'.format('SUCCESS\n',
                               "generate unsigned transaction file:", csvPath))
        end = datetime.datetime.now()
        print("end:{}".format(end))
        print("总共消耗时间:{}s".format((end - start).seconds))
        sys.exit(0)
Ejemplo n.º 14
0
class Ppos:
    def __init__(self, url, address, privatekey, chainid=101):
        self.web3 = connect_web3(url)
        if not self.web3.isConnected():
            raise Exception("node connection failed")
        self.eth = Eth(self.web3)
        self.address = Web3.toChecksumAddress(address)
        self.privatekey = privatekey
        self.gasPrice = 1000000000
        self.gas = "0x6fffff"
        self.chainid = chainid

    def get_result(self, tx_hash):
        result = self.eth.waitForTransactionReceipt(tx_hash)
        """查看eventData"""
        data = result['logs'][0]['data']
        if data[:2] == '0x':
            data = data[2:]
        data_bytes = rlp.decode(bytes.fromhex(data))[0]
        event_data = bytes.decode(data_bytes)
        event_data = json.loads(event_data)
        print(event_data)
        return event_data

    def send_raw_transaction(self,
                             data,
                             from_address,
                             to_address,
                             gasPrice,
                             gas,
                             value,
                             privatekey=None):
        nonce = self.eth.getTransactionCount(from_address)
        print('nonce: ', nonce)
        if not privatekey:
            privatekey = self.privatekey
        if value > 0:
            transaction_dict = {
                "to": to_address,
                "gasPrice": gasPrice,
                "gas": gas,
                "nonce": nonce,
                "data": data,
                "chainId": self.chainid,
                "value": self.web3.toWei(value, "ether")
            }
        else:
            transaction_dict = {
                "to": to_address,
                "gasPrice": gasPrice,
                "gas": gas,
                "nonce": nonce,
                "data": data,
                "chainId": self.chainid
            }
        signedTransactionDict = self.eth.account.signTransaction(
            transaction_dict, privatekey)
        data = signedTransactionDict.rawTransaction
        result = HexBytes(self.eth.sendRawTransaction(data)).hex()
        return result

    def createStaking(self,
                      typ,
                      benifitAddress,
                      nodeId,
                      externalId,
                      nodeName,
                      website,
                      details,
                      amount,
                      programVersion,
                      programVersionSign,
                      blsPubKey,
                      blsProof,
                      privatekey=None,
                      from_address=None,
                      gasPrice=None,
                      gas=None):
        to_address = "0x1000000000000000000000000000000000000002"
        if benifitAddress[:2] == '0x':
            benifitAddress = benifitAddress[2:]
        if programVersionSign[:2] == '0x':
            programVersionSign = programVersionSign[2:]
            data = HexBytes(
                rlp.encode([
                    rlp.encode(int(1000)),
                    rlp.encode(int(typ)),
                    rlp.encode(bytes.fromhex(benifitAddress)),
                    rlp.encode(bytes.fromhex(nodeId)),
                    rlp.encode(externalId),
                    rlp.encode(nodeName),
                    rlp.encode(website),
                    rlp.encode(details),
                    rlp.encode(self.web3.toWei(amount, 'ether')),
                    rlp.encode(programVersion),
                    rlp.encode(bytes.fromhex(programVersionSign)),
                    rlp.encode(bytes.fromhex(blsPubKey)),
                    rlp.encode(bytes.fromhex(blsProof))
                ])).hex()
            if not privatekey:
                privatekey = self.privatekey
            if not from_address:
                from_address = self.address
            if not gasPrice:
                gasPrice = self.gasPrice
            if not gas:
                # transactiondict = {"to": to_address, "data": data}
                gas = self.gas
            result = self.send_raw_transaction(data, from_address, to_address,
                                               gasPrice, gas, 0, privatekey)
            return self.get_result(result)

    def apply_delegate(self,
                       typ,
                       nodeId,
                       amount,
                       privatekey=None,
                       from_address=None,
                       gasPrice=None,
                       gas=None):
        to_address = "0x1000000000000000000000000000000000000002"
        data = rlp.encode([
            rlp.encode(int(1004)),
            rlp.encode(int(typ)),
            rlp.encode(bytes.fromhex(nodeId)),
            rlp.encode(self.web3.toWei(amount, 'ether'))
        ])
        if not privatekey:
            privatekey = self.privatekey
        if not from_address:
            from_address = self.address
        if not gasPrice:
            gasPrice = self.gasPrice
        if not gas:
            transactiondict = {"to": to_address, "data": data}
            gas = self.eth.estimateGas(transactiondict)
        result = self.send_raw_transaction(data, from_address, to_address,
                                           gasPrice, gas, 0, privatekey)
        return self.get_result(result)

    def getCandidateInfo(self, nodeId):
        data = rlp.encode(
            [rlp.encode(int(1105)),
             rlp.encode(bytes.fromhex(nodeId))])
        to_address = "0x1000000000000000000000000000000000000002"
        raw_data = self.eth.call({
            "from": self.address,
            "to": to_address,
            "data": data
        })
        parse = str(raw_data, encoding="utf8").replace('\\', '').replace(
            '"{', '{').replace('}"', '}')
        receive = json.loads(parse)
        try:
            raw_data_dict = receive["Ret"]
            raw_data_dict["Shares"] = int(raw_data_dict["Shares"], 16)
            raw_data_dict["Released"] = int(raw_data_dict["Released"], 16)
            raw_data_dict["ReleasedHes"] = int(raw_data_dict["ReleasedHes"],
                                               16)
            raw_data_dict["RestrictingPlan"] = int(
                raw_data_dict["RestrictingPlan"], 16)
            raw_data_dict["RestrictingPlanHes"] = int(
                raw_data_dict["RestrictingPlanHes"], 16)
            raw_data_dict["DelegateRewardTotal"] = int(
                raw_data_dict["DelegateRewardTotal"], 16)
            raw_data_dict["DelegateTotal"] = int(
                raw_data_dict["DelegateTotal"], 16)
            raw_data_dict["DelegateTotalHes"] = int(
                raw_data_dict["DelegateTotalHes"], 16)
            receive["Ret"] = raw_data_dict
        except:
            ...
        return receive

    def getCandidateList(self):
        """
        Query all real-time candidate lists
        :param from_address: Used to call the rpc call method
        :return:
        todo fill
        """
        data = rlp.encode([rlp.encode(int(1102))])
        raw_data = self.eth.call({
            "from": self.address,
            "to": '0x1000000000000000000000000000000000000002',
            "data": data
        })
        parse = str(raw_data, encoding="utf8").replace('\\', '').replace(
            '"{', '{').replace('}"', '}')
        try:
            raw_data = parse["Ret"]
            for i in raw_data:
                i["Shares"] = int(i["Shares"], 16)
                i["Released"] = int(i["Released"], 16)
                i["ReleasedHes"] = int(i["ReleasedHes"], 16)
                i["RestrictingPlan"] = int(i["RestrictingPlan"], 16)
                i["RestrictingPlanHes"] = int(i["RestrictingPlanHes"], 16)
        except:
            ...
        return parse

    def getVerifierList(self):
        """
        Query the certified queue for the current billing cycle
        :param from_address: Used to call the rpc call method
        :return:
        todo fill
        """
        data = rlp.encode([rlp.encode(int(1100))])
        raw_data = self.eth.call({
            "from": self.address,
            "to": '0x1000000000000000000000000000000000000002',
            "data": data
        })
        parse = str(raw_data, encoding="utf8").replace('\\', '').replace(
            '"{', '{').replace('}"', '}')
        try:
            raw_data = parse["Ret"]
            for i in raw_data:
                i["Shares"] = int(i["Shares"], 16)
        except:
            ...
        return parse