Example #1
0
    def send(self, to, value, price=4):
        '''
        :param to: Hex string of payment receiver.
        :param value: Value in Ether
        :param price: Price of gas
        :return: Receipt of the transaction.
        '''
        # Gas estimation also depends on the specified ethereum network

        nonce = self.web3.eth.getTransactionCount(self.key.address)
        gas = self.web3.eth.estimateGas({
            'to': to,
            'from': self.key.address,
            'value': Web3.toWei(value, 'ether')
        })
        trans = {
            'to': to,
            'value': Web3.toWei(value, 'ether'),
            'gas': gas,
            'gasPrice': Web3.toWei(price, 'gwei'),
            'nonce': nonce,
            'chainId': netIds[self.network]
        }

        #self.web3.eth.enable_unaudited_features()
        signObj = self.web3.eth.account.signTransaction(
            trans, self.key.getPrivate())
        try:
            txnHash = self.web3.eth.sendRawTransaction(signObj.rawTransaction)
        except Exception as e:
            print(e + ' ' + str(type(e)))
        else:
            return self.wait_for_receipt(byte32(txnHash), 10)
Example #2
0
    def call(self, contractAddress, methodName, *arg, price=4, value=0):
        '''
        Broadcasts a method call transaction to the network.
        :param contractAddress: HexString address of a contract deployed through Nim.
        #TODO: Let people load their own abi ?
        :param methodName: (string)
        :param arg: Respective arguments for the method
        :param price: (unsigned int) price in gwei for gas
        :param value: (ether)value for the transaction in ether.
        :return: tuple with locally calculated return value at [0] and transaction receipt at [1].
        '''
        self.c.execute('SELECT contractObj FROM Deployed WHERE address = ?',
                       (contractAddress, ))
        data = self.c.fetchone()
        if data == None:
            raise exc.ContractNotDeployed('Infura.call()')
        interface = pickle.loads(data[0])
        contract = self.web3.eth.contract(abi=interface['abi'],
                                          bytecode=interface['bin'],
                                          address=contractAddress)
        #print(contract.functions.__dict__.keys())
        if methodName not in contract.functions.__dict__.keys():
            raise exc.MethodNotDefined('Infura.call()')
        if methodName == 'fallback':
            func = contract.functions.fallback
        else:
            func = contract.functions.__dict__[methodName]

        counter = 0
        b = True
        while True:
            try:
                counter += 1
                nonce = self.web3.eth.getTransactionCount(self.key.address)
                trans = {
                    'gasPrice': Web3.toWei(price, 'gwei'),
                    'value': Web3.toWei(value, 'ether'),
                    'nonce': nonce,
                    'chainId': netIds[self.network],
                    'from': self.address,
                    'gas': 90000
                }
                txn = func(*arg).buildTransaction(trans)

            except ValueError as e:
                print(type(e.args[0]))

            else:
                print('Cost of method calling : ' + str(
                    self.web3.fromWei(
                        txn['gasPrice'] * txn['gas'] +
                        txn['value'], 'ether')) + ' ETH')
                signObj = self.web3.eth.account.signTransaction(
                    txn, self.key.getPrivate())
                txnHash = byte32(
                    self.web3.eth.sendRawTransaction(signObj.rawTransaction))
                return (func(*arg).call(), self.wait_for_receipt(txnHash, 5))
Example #3
0
    def deploy(self, path, *arg, price=2, value=0):
        '''
        Deploys a solidity source file and returns the address of the contract.
        Also stores the serialized compile object on a sql database.
        '''
        # self.c.execute('SELECT address FROM Deployed WHERE address = ?', (contractAddress,))

        solname = path
        path = solpath + path
        f = open(path, 'r')
        compiled_sol = compile_source(f.read())
        f.close()
        contractName, contract_interface = compiled_sol.popitem()
        blob = pickle.dumps(contract_interface)
        bin, abi = contract_interface['bin'], contract_interface['abi']
        contract = self.web3.eth.contract(abi=abi, bytecode=bin)
        nonce = self.web3.eth.getTransactionCount(self.key.address)

        trans = {
            'gasPrice': Web3.toWei(price, 'gwei'),
            'value': Web3.toWei(value, 'ether'),
            'nonce': nonce,
            'chainId': netIds[self.network],
            'from': self.address
        }
        if arg == None:
            txn = contract.constructor().buildTransaction(trans)
        else:
            txn = contract.constructor(*arg).buildTransaction(trans)

        print('Cost of deployment: ' + str(
            self.web3.fromWei(txn['gasPrice'] * txn['gas'] +
                              txn['value'], 'ether')) + ' ETH')

        signObj = self.web3.eth.account.signTransaction(
            txn, self.key.getPrivate())

        try:
            txnHash = self.web3.eth.sendRawTransaction(signObj.rawTransaction)
        except ValueError as e:
            print(type(e.args[0]))

        txnHash = byte32(txnHash)

        address = self.wait_for_receipt(txnHash, 10)['contractAddress']

        entry = (address, solname, blob, datetime.datetime.now())
        self.c.execute(
            'INSERT INTO Deployed(address,filename,contractObj,dat) VALUES (?,?,?,?)',
            entry)
        self.conn.commit()
        return address
Example #4
0
    def test_hash(self):
        print('...test_hash()')

        stri = 'this is a test'

        sign = self.A.signStr(stri)
        self.assertEqual(self.A.address, self.A.whoSign(sign.messageHash, sign.signature))
        print("...Local string hashing test passed.")
        print("...Recover signer from signature obj test passed.")

        address = self.A.deploy('test3.sol')

        print("...test3.sol contract deployed")
        
        a = self.B.call(address,'hash',4)[0]
        b = soliditySha3(['uint256'], [4])
        self.assertEqual(a, b)

        hash1 = self.B.call(address, 'hashSenderAddress')[1]['logs'][0]['data']
        hash2 = byte32(soliditySha3(['address'], [self.B.address]))
        rAddress = self.B.call(address, 'returnAddress')[1]
        rAddress =rAddress['logs'][0]['data']

        print("msg.sender(Event): "+ str(rAddress))
        print("msg.sender(self.B.address): " +self.B.address)
        print("Calculated Hash of address(EVM event): "+str(hash1))
        print("Web3Py calculated byte32(keccak256(address)): "+ hash2)

        self.assertEqual(hash1,hash2)

        hash3 = self.B.call(address,'hashSpecial',10,3)[1]['logs'][0]['data']
        hash4 = byte32(soliditySha3(['address','uint256','uint256','address'], [self.B.address,10,3,address]))
        print("EVM keccak256(msg.sender,amount,nonce,this): " + str(hash3))
        print('Web3Py calculated byte32(print("EVM keccak256(msg.sender,amount,nonce,this))'+ hash4)
        self.assertEqual(hash3, hash4)
        print()
Example #5
0
    def write(self,recipient,amount):
        '''

        :param recipient: Address of check recipient(HexString).
        :param amount: Amount in ether to be sent.(int)
        :return: json with
        '''
        self.address = self.connection.deploy('check.sol',price=4, value=amount)
        nonce = random.randrange(1,10000)
        while nonce in self.nonces:
            nonce = random.randrange(1,10000)
        print('Check deployed at: ' + self.address)
        amount = Web3.toWei(amount, 'ether')
        hash = byte32(soliditySha3(["address", "uint256","uint256","address"], [recipient, amount,nonce,self.address]))
        sign = format(self.connection.signHash(hash))
        check = {'address':self.address,'amount':amount,'nonce':nonce,'msgHash':sign[0],
                 'v':sign[1],'r':sign[2],'s':sign[3]}
        return json.dumps(check)