0

I am getting this exception, when I am using sendrawtransaction. And all I want to do is translate this docs to Python code, and I have searched for a while but both Can anyone shed any light on this error? Bitcore Multisig - bad-txns-in-belowout and Bitcoin core “bad-txns-in-belowout” can't make me clear. and all the exception traceback are list as below:

Traceback (most recent call last):

File "multisign.py", line 137, in print(ms.go()) File "multisign.py", line 128, in go ret = self.rpc.sendrawtransaction(last_hex) File "/Users/frank/venv/bitcoin/lib/python2.7/site-packages/bitcoinrpc/authproxy.py", line 141, in call raise JSONRPCException(response['error']) bitcoinrpc.authproxy.JSONRPCException: -26: 16: bad-txns-in-belowout

Whole my python code as following:

import json
import binascii
from pprint import pprint
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException

# rpc_user and rpc_password are set in the bitcoin.conf file
rpc_user = 'my_rpc'
rpc_password= 'my_rpc_password'
rpc_host = '192.168.1.86:9332'

rpc_connection = AuthServiceProxy("http://{}:{}@{}".format(rpc_user, rpc_password, rpc_host))

#print(best_block_hash)

class MultiSign(object):

    def __init__(self, rpc):
        self.rpc = rpc


    def validate_address(self, addr):
        ret = self.rpc.validateaddress(addr)
        return ret

    def pubkey(self):
        pass


    def set_addr(self, addr_1, addr_2, addr_3, addr_4):
        self.addr_1 = addr_1
        self.addr_2 = addr_2
        self.addr_3 = addr_3
        self.addr_4 = addr_4


    def create_multisig(self, nrequired, keys):
        """
        Deprecated this <createmultisig>

        @param nrequired: numeric
        @param keys: string A json array of hex-encoded public keys

        @return {"address":"multi_sign_address", "redeemScript":"script"}
        """
        return self.rpc.createmultisig(nrequired, keys)

    def add_multisig_address(self, nrequired, keys):
        return self.rpc.addmultisigaddress(nrequired, keys)

    def dumpprivkey(self, addr):
        return self.rpc.dumpprivkey(addr)

    def send_address(self, addr, amount):
        return self.rpc.sendtoaddress(addr, amount)

    def get_rawtransaction(self, txid, flag=1):
        return self.rpc.getrawtransaction(txid, flag)

    def create_raw(self, txid, vout, dest_addr, amount):
        pass

    def go(self):
        total_amount = self.rpc.getbalance()
        print(total_amount)
        utxo_vout = 0
        addr1 = self.rpc.getnewaddress()
        addr2 = self.rpc.getnewaddress()
        addr3 = self.rpc.getnewaddress()
        addr4 = self.rpc.getnewaddress() # destination address which we will send to 
        raw_change_address = self.rpc.getrawchangeaddress()
        fee_obj = self.rpc.estimatesmartfee(6)
        fee = fee_obj.get("feerate")

        send_amount = total_amount / 2
        change_amount = total_amount / 2 -  fee
        print("send_amount -->%s" % send_amount)

        if change_amount < 0.00001:
            print(change_amount)
            raise Exception("Insufficient funds")
        change_amount = "%.8f" % change_amount
        send_amount = "%0.8f" % send_amount
        # ======

        data = "@landpack"
        if len(data) > 75:
            print("Data length is {}".format(len(data)))
            raise Exception("Too much data, use OP_PUSHDATA1 instead")

        hex_format_data = binascii.hexlify(data)


        # validate each address
        #pub_obj_addr1 = self.validate_address(addr1)
        #pub_obj_addr2 = self.validate_address(addr2)
        #pub_key_addr1 = pub_obj_addr1.get("pubkey")
        #pub_key_addr2 = pub_obj_addr2.get("pubkey")
        pub_obj_addr3 = self.validate_address(addr3)
        pub_key_addr3 = pub_obj_addr3.get("pubkey")
        # dump prive key ..
        priv_addr1 = self.dumpprivkey(addr1)
        priv_addr2 = self.dumpprivkey(addr2)
        priv_addr3 = self.dumpprivkey(addr3)
        # add multi sign address
        ret = self.add_multisig_address(2, [addr1, addr2, pub_key_addr3])
        print("==" * 10)
        print(ret)
        addr5 = ret.get("address")
        redeemScript = ret.get("redeemScript")
        #
        txid = self.send_address(addr5, send_amount)
        # check the transaction by txid
        ret = self.get_rawtransaction(txid, 1)
        vout_obj = ret.get("vout")
        scriptPubKey = vout_obj[0].get("scriptPubKey")
        hex_value = scriptPubKey.get("hex")
        # create a raw transaction
        ret_hash = self.rpc.createrawtransaction([{"txid": txid, "vout": utxo_vout}], {"data":hex_format_data, addr4: send_amount, raw_change_address: change_amount})
        # sign transaction
        sign_raw_transaction = self.rpc.signrawtransaction(ret_hash, [{"txid":txid, "vout":utxo_vout, "redeemScript": redeemScript, "scriptPubKey": hex_value, "amount": send_amount}],[ priv_addr1])

        # ..
        party_hex = sign_raw_transaction.get("hex")
        sign_party_transaction = self.rpc.signrawtransaction(party_hex, [{"txid":txid, "vout":utxo_vout, "redeemScript": redeemScript, "scriptPubKey": hex_value, "amount": send_amount}],[ priv_addr3])
        # send to brodcas
        last_hex = sign_party_transaction.get("hex")
        print(sign_party_transaction)
        ret = self.rpc.sendrawtransaction(last_hex)


        return ret

if __name__ == '__main__':
    addr = 'tb1qffcx4mpft5lxk9clsz2du4t03elxl4qwx2hu8z'
    ms = MultiSign(rpc=rpc_connection)
    ms.validate_address(addr)
    print(ms.go())

1 Answer 1

2

That error means that you are trying to spend more money than you have inputs for. In other words, value in < value out. You need to add more inputs so the total input value exceeds the total output value.

You need to get unspent outputs from previous transactions which you have received at the address your trying to send from. Have a look at listreceivedbyaddress from blockchain.info api.

2
  • Well, I have tried to get the balance by total_amount = rpc_connection.listunspent()[0], but still show me the same exception.
    – Frank AK
    Jul 26, 2018 at 5:52
  • Can you share some of the output the other print statements? It's hard to debug without knowing the balance, and what the raw transaction looks like.
    – JBaczuk
    Jul 26, 2018 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.