Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error choosing inputs for the send transaction #760

Open
initsysctrl opened this issue Aug 30, 2018 · 37 comments
Open

Error choosing inputs for the send transaction #760

initsysctrl opened this issue Aug 30, 2018 · 37 comments

Comments

@initsysctrl
Copy link

When I was planning to send USDT, there was an error. I am sure my balance of USDT&BTC is adequate.

$ ./omnicore-cli omni_funded_send "mrAVAPxdQEZxFkunh56skB6sgJa6vrfrpo" "msJ2h47ZrxFJjksVvPy8ik4h2HFfa9W1zV" 31 "100.01" "mpaumxor659PhoJhXp1VCVHVwbFCZSRmuf"
error code: -212
error message:
Error choosing inputs for the send transaction
@congnghiakhiem
Copy link

please try omni_send.

Example:

$ omnicore-cli "omni_send" "3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY" "37FaKponF7zqoMLUjEiko25pDiuVH5YLEa" 1 "100.0"

https://github.com/OmniLayer/omnicore/blob/master/src/omnicore/doc/rpc-api.md#omni_send

@alesito85
Copy link

@congnghiakhiem is there a problem with omni_funded_send? Because I'm having the same issue with omni_funded_sendall. The from address has a tiny amount of BTC balance but the funding address has a lot of BTC.

Any ideas about how to debug this?

@krazedkrish
Copy link

krazedkrish commented Sep 6, 2018

My I software requires me to use only one address to store btc and the rest to to store usdt. Therefore I was hoping to use omni_funded_send instead of omni_send in json api, because if there are bitcoins missing from source address, they are taken from the specified fee source. But I am stuck with the same error message lik @initsysctrl .

The following was the output from json_rpc request:
-- Request Method --
POST

-- Request headers --
{"Authorization":"Basic YXVkZXg6dGVzdDEyMw==","User-Agent":"Faraday v0.14.0","Accept":"application/json","Content-Type":"application/json"}

-- Request body --
{"jsonrpc":"1.0","method":"omni_funded_send","params":["mgHbG2fYMwhTW9XWGU8f6jRNKd2QVUySiE","mgHbG2fYMwhTW9XWGU8f6jRNKd2QVUySiE",2,"4.1","n3MicAyoHhwVaALe7wCGiQ6KaWQJxu36u7"]}

-- Response headers --
{"content-type":"application/json","date":"Thu, 06 Sep 2018 01:08:05 GMT","content-length":"107","connection":"close"}

-- Response body --
{"result":null,"error":{"code":-212,"message":"Error choosing inputs for the send transaction"},"id":null}

@initsysctrl
Copy link
Author

initsysctrl commented Sep 6, 2018

@congnghiakhiem The method "omni_send" must need bitcoin in the sender, which is not recommended after version 0.3.1. Because I need the sole payer of the commission fee.but also thank you.

@samueldeng
Copy link

bitcoins from the sender are consumed and if there are bitcoins missing, they are taken from the specified fee source. Change is sent to the fee source
which ridiculouly means that if there are not any btc in sendadress, it would be error.

@dexX7 But it's still a question that why the code is implemented by that?

wallettxbuilder.cpp: 231-234

    if (!SelectAllCoins(senderAddress, coinControl)) {
        PrintToLog("%s: ERROR: sender %s has no coins\n", __func__, senderAddress);
        return MP_INPUTS_INVALID;
    }

@achamely
Copy link

@samueldeng The Omni Protocol spec stats that the 'sender' of a transaction is the address associated with the first utxo in that transaction.
This means that regardless of where the additional btc is sourced from for miner fee's etc. the very first utxo must come from the address the funds are being sent/transferred from .
If that address has no btc/utxos, then it is impossible to create a valid transaction and the process fails.

@alesito85
Copy link

@achamely I have a situation where I have BTC in the send address (the minimum that I got when I received tokens) and there doesn't seem to be any way to use omni_funded_send or omni_funded_sendall. I always get "Error with selected inputs for the send transaction". The fee address does have BTC balance that is sufficient for tx.
How to go ahead from here?

@achamely
Copy link

@alesito85 what are the 2 addresses you are using and the omnicore-cli command you are trying?
What is the output of omnicore-cli getinfo
Also can you post the output from omnicore-cli validateaddress <youraddress> for each of the addresses you are trying to send from / use as funding source

@iwinniepooh
Copy link

Have same problem.
All address
"isvalid": true,
"ismine": true

feeaddress have alot of BTC, but i still have error: -212 Error choosing inputs for the send transaction

@alesito85
Copy link

The address has been verified and was valid and mine. What helps though is restarting the omnicored node. Strange, but it does... I've had plenty of balance everywhere and it didn't work. But when I've restarted the node the transactions were possible. And this was done multiple times.

@achamely
Copy link

@rupsyde @alesito85 one other thing to note is that if your omnicore client is not fully synced it will not be able to properly use any balances it has not parsed yet.
The getinfo command will show you the current block it's reached/parsed. Please make sure the client is 100% synced/caught up to the current blockchain before trying to use it

@litch
Copy link

litch commented Oct 31, 2018

I've come back to this thread a few times because I was totally stumped, and think I may have figured out why a lot more people are seeing this than would be expected (including me). Pardon me if the language is a bit imprecise:

You need UTXO’s in an OMNI address to send OMNI-layer transactions (not super surprising) out of that address.

In practice, what this means is that if: you receive some USDT to a fresh address, and want to send some of the USDT out of that address you can do a “funded send” to pay the transaction fee out of a “fee address” you have (great!). However, what you then wind up with is an address that has some OMNI but no UTXO’s (you consumed it in the previous transaction). So now, even though you can pay the fee to send the remaining USDT from that address to another using “funded_send”, you can’t actually compose a transaction out of that address, since you have consumed the UTXO. So now you need to send some bitcoin (or whatever you want to do) to that address again to get it a UTXO, with which it can compose the funded_send transaction.

  1. Receive 10 OMNI to fresh address abdce...
  2. Send 5 OMNI to another address using omni_funded_send - ✅
  3. Try to send the remaining 5 OMNI to another address using omni_funded_send - ❗️
    • You will get the error -212 because it can't find a UTXO to send that last 5 OMNI on (regardless of whether you have BTC in the fee address)

It seems like a great added feature of the OMNI protocol would be to, when composing a funded_send that is not going to send ALL the omni properties from a given address, address a UTXO back to the origin - conceptually like a "change" transaction...

@initsysctrl
Copy link
Author

@litch right,This is indeed the case,and there's no better way to fix this than by sending bitcoin.That said, I can only send usdt or other omni'asset once,The second time will get an error,-212. Do you have a better plan?

@initsysctrl
Copy link
Author

@initsysctrl I validated the address and made sure it was valid, but there were still the same mistakes as you. Why?
in fact ,You can send it successfully the first time,�the sender address must need a litter utxo .

@apa7
Copy link

apa7 commented Nov 13, 2018

method: omni_funded_send,
params: [myVEjv5RF3MvKcYqsHGDLWTM6sUjjYcbaY, 2NGZrVvZG92qGYqzTLjCAewvPZ7JE8S8VxE, 2, 0.1, mmC1z9b1U6H8FS1jR95KnGkykhgHAS1hXD],
response: {"result":null,"error":{"code":-212,"message":"Error choosing inputs for the send transaction"},"id":"1"}

1.address is valid
2.call method: omni_getwalletaddressbalances,
response:
{
"address": "myVEjv5RF3MvKcYqsHGDLWTM6sUjjYcbaY",
"balances": [
{
"propertyid": 1,
"name": "Omni",
"balance": "20.00000000",
"reserved": "0.00000000",
"frozen": "0.00000000"
},
{
"propertyid": 2,
"name": "Test Omni",
"balance": "20.00000000",
"reserved": "0.00000000",
"frozen": "0.00000000"
}
]
}

token is enough
3.call method listaddressgroupings
response:
[
"mmC1z9b1U6H8FS1jR95KnGkykhgHAS1hXD",
0.35000000,
""
]
...
btc is enough

@apa7
Copy link

apa7 commented Nov 13, 2018

This problem has been solved. When using the method omni_funded_send to send tokens, fromAddress should have a bit of btc.It means that the "feeaddress" does not pay all the fees.
As the error resp said,
"All bitcoins from the sender are consumed and if there are bitcoins missing, they are taken from the specified fee source."

@ngocbd
Copy link

ngocbd commented Dec 5, 2018

I confirm this issue still happen.

@buiminhhuy
Copy link

The issue was occurred when sending 25 times on the same sending accounts.

@buiminhhuy
Copy link

buiminhhuy commented Mar 25, 2019

Quick fix by pass limit 25 transaction, should be add two configs to your command. or setting tether.conf
-limitancestorcount=100
-limitdescendantcount=100
But, this fix will occur a bug: A lot of transaction in pool un confirmation. Cannot broadcast to another nodes.
Anyone have good idea? Maybe increase fee sending coin by command omnicore-cli "omni_send", adjust new fee with same calculate + delta fee for quickly confirmation.
Thanks,
Huy Bui

@xiaods
Copy link

xiaods commented Apr 9, 2019

I confirm this issue still happen.
if the address have no UTXO, it can't send any coin.

@WilliamXie9
Copy link

Still happen.
I try to construct omni_funded_send transaction without RPC API, and I found the omni_funded_send API actually add new inputs for paying fee. Construct that transaction, you need the inputs for sender address, mean you need utxo of sender address, but this utxo‘s amount can be 0 which comes from previous transaction - like user deposit.
This is the transaction i construct:
https://www.blockchain.com/btctest/tx/03d56a0c18fd115c5fdee42e62c544dfa3194e1ff6102621750985da39a4cb60
FYI:
https://medium.com/omnilayer/introducing-funded-omni-layer-transactions-or-how-exchanges-can-save-money-f3f04161a6af

@dmitryrn
Copy link

@WilliamXie9 can you please specify steps how did you do that? Using raw-transaction RPCs, right?

@WilliamXie9
Copy link

WilliamXie9 commented May 20, 2019

@WilliamXie9 can you please specify steps how did you do that? Using raw-transaction RPCs, right?

@dmitryrn sure
`

    val network = TestNet3Params.get()
    var client = OmniCLIClient(network, URI("http://xxx.xxx.xxx.xxx:xxx"), "username", "password")
    var client2 = BitcoinJSONRPCClient(URL("http://name:password@xx.xx.xx.xx:xx/"))


    // 1 list unspent outputs
    client2.importAddress("mznoRw5ingAqQAXEhxxxxzAkRgc2aAC7", "test", false)
    var feeUtxoList = client2.listUnspent(0, 999999, "mznoRw5ingAqQAXEhxxxxzAkRgc2aAC7")
    var senderUtxoList = client2.listUnspent(0, 999999, "mmf3TtdKNHdV7byWxxxxxGbiRCVrVnB3Bd")

    // 3 construct transaction base, add sender address
    var tx1 = Transaction(network)
    tx1.addInput(Sha256Hash.wrap(senderUtxoList[0].txid()),
            senderUtxoList[0].vout().toLong(),
            Script(NumericUtil.hexToBytes(senderUtxoList[0].scriptPubKey())))


    // 3.2 add fee address
    tx1.addInput(Sha256Hash.wrap(feeUtxoList[0].txid()),
            feeUtxoList[0].vout().toLong(),
            Script(NumericUtil.hexToBytes(feeUtxoList[0].scriptPubKey())))

    // 4 attach payload output
    var op = BigDecimal(0.50700001).times(BigDecimal(10).pow(8)).toLong()
    tx1.addOutput(Coin.valueOf(0), Script(Hex.decode("6a146f6d6e69" + String.format("%016x", 1) + String.format("%016x", op))))

    // 5 attach reference/receiver output
    tx1.addOutput(Coin.valueOf(0), Address.fromString(network, "mzwB28AkTn1A2wUd7xxxxxaZsPxMFc3FnY"))

    // 6 specify miner fee and attach change output
    tx1.addOutput(Coin.valueOf(6700000), Address.fromString(network, "mznoRw5ingAqQAXEhxxxxzAkRgc2aAC7"))

    // 7 sign transaction
    // a: sender sign
    var ecKey = DumpedPrivateKey.fromBase58(network, "cQRYVgbejCXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxm8oHCMik9WS").key
    var scriptPubKey = ScriptBuilder.createOutputScript(org.bitcoinj.core.Address.fromString(network, "mmf3TtdKNHdV7byWxxxxxGbiRCVrVnB3Bd"))
    var hash = tx1.hashForSignature(0, scriptPubKey, Transaction.SigHash.ALL, false)
    var txSig = TransactionSignature(ecKey.sign(hash), Transaction.SigHash.ALL, false)
    tx1.inputs[0].scriptSig = ScriptBuilder.createInputScript(txSig, ecKey)
    // b: fee address sign
    var ecKey2 = DumpedPrivateKey.fromBase58(network, "cQHGQGVFMjTEixxxxxxxxxxxxxxxxxxxxxxxxxxL2bwdqK6dQoMh").key
    var scriptPubKey2 = ScriptBuilder.createOutputScript(org.bitcoinj.core.Address.fromString(network, "mznoRw5ingAqQAXEhxxxxzAkRgc2aAC7"))
    var hash2 = tx1.hashForSignature(1, scriptPubKey2, Transaction.SigHash.ALL, false)
    var txSig2 = TransactionSignature(ecKey2.sign(hash2), Transaction.SigHash.ALL, false)
    tx1.inputs[1].scriptSig = ScriptBuilder.createInputScript(txSig2, ecKey2)


    // 8 broadcast transaction
    var newBroadcastTxId = client.sendRawTransaction(NumericUtil.bytesToHex(tx1.bitcoinSerialize()))`

@dmitryrn
Copy link

dmitryrn commented May 21, 2019

Anyone who searching for solution, I researched one.

Idea is to use one address with big amount of BTC to pay transaction fees, one called feeSpender. I create output back to sender address with tiny amount of BTC, so it will be possible to create another transaction and use feeSpender's balance to pay fees.

Only issue with this is: if you have multiple addresses who want to make transactions using single feeSpender, you must wait until previous transaction confirmed, because you using feeSpender's outputs. One can solve this by creating multiple outputs to feeSpender and use several of outputs when creating transaction or use multiple feeSpender's to create "multithreading" when send transactions.

And another issue: this use all of feePayer's inputs, it will cause in unnecessary big transaction size, so you could improve this and use only as many inputs as needed.

import a from 'axios'

const p = async (method, ...params) => (await a.post('http://localhost:8332', { method, params }, {
  auth: {
    username: '123',
    password: '456'
  }
})).data.result

const from = 'fromaddr'
const to = 'toaddr'
const feeSpender = 'feepayeraddr'

Promise.resolve().then(async () => {
  const payload = await p('omni_createpayload_simplesend', 31, '1')

  const unspentReceiverInputs = await p('listunspent', 3, 999999, [from])

  const unspentFeePayerInputs = await p('listunspent', 3, 999999, [feeSpender])

  const inputsUsed = unspentReceiverInputs.concat(unspentFeePayerInputs)

  // 0.0000546 is tiny amount to send back to sender so it will able
  // to send another transaction after confirmation of this one
  const txBase = await p('createrawtransaction', inputsUsed, { [from]: '0.0000546' })

  const txBaseWithPayload = await p('omni_createrawtx_opreturn', txBase, payload)

  const txBaseWithPayloadAndReceiverOutput = await p('omni_createrawtx_reference', txBaseWithPayload, to)

  const withChangeOutput = await p('omni_createrawtx_change',
    txBaseWithPayloadAndReceiverOutput,
    inputsUsed.map(({ amount: value, ...input }) => ({ ...input, value })),
    feeSpender,
    '0.00028865') // this is a tx fee

  const { hex: signedTx } = await p('signrawtransaction', withChangeOutput)

  const decoded = await p('decoderawtransaction', signedTx)

  const txid = await p('sendrawtransaction', signedTx)
}).catch(r => console.log(r.response.data))

@dmitryrn
Copy link

dmitryrn commented May 21, 2019

And please tell me if I can use more simplistic solution @dexX7

@dexX7
Copy link
Member

dexX7 commented May 21, 2019

Hey @dmitryrn @WilliamXie9,

can you quickly describe why/how funded send is not appropriate for your use case?

In it's current form it consumes all BTC from the specified sender and transfers the specified amount of tokens (or sends any, if omni_funded_sendall is used). If not enough BTC are available for the send, the rest is taken from the specified fee source. However, there is always the need for at least one UTXO from the sender.

@dmitryrn
Copy link

dmitryrn commented May 21, 2019

@dexX7 The reason I can't use send/funded send is they does not leave UTXO on sender address (as I understand, I actually tested it). So in my method I create UTXO on sender address during transaction to be able to create another transaction from this address.

@dexX7
Copy link
Member

dexX7 commented May 21, 2019

Hmm.. is this for a token hot wallet or just for two sends in a row? If it's for a wallet, which is used multiple times, I'd suggest you could just send some BTC to it to keep it funded.

@dmitryrn
Copy link

Yes, send BTC to this address required sending transaction, and paying fees for it, but in my case another address pay fees and I don't want to manually send BTC to sender address after transaction. It will just have UTXO with tiny amount.

@dexX7
Copy link
Member

dexX7 commented May 21, 2019

@dmitryrn: what would you recommend, if we'd go to change the funded sending commands or add a new one?

@dmitryrn
Copy link

dmitryrn commented May 21, 2019

@dexX7 I guess people confused with situation like this: You have 2 USDT on your address and a bit BTC, then you send 1 USDT with send/funded send and hoping you can send remaining 1 USDT later, but you can't, because these methods spent UTXO's.

And I'm not really sure what to do with that because it's default, like right, behaviour in bitcoin context. Maybe we just should create page on wiki with such use case? Or maybe we should add some description about UTXO in RPC description for send/funded send?

I'm not sure about new method creation or changing existing one.

@WilliamXie9
Copy link

Hi @dexX7 I have the same problem with @dmitryrn . Just like @dmitryrn say, maybe should add some description about UTXO in RPC for funded send.

@skybat007
Copy link

mark

@dwjorgeb
Copy link

this is quite a major issue to be completely fair. Even more when you need to split payments.

Let's say you receive 2 USDT on address X
Then you want to send 1 USDT to Address A and 1 USDT to Address B

You can't send them on the same TX as OMNI doesn't support sendmany, and you can't send the 2nd TX because you've ran out of UTXOs.

There should be a way to solve this issue

@litch
Copy link

litch commented Dec 26, 2019 via email

@dexX7
Copy link
Member

dexX7 commented Apr 24, 2020

Hey guys,

initially the funded send was introduced to help exchanges to "sweep" all incoming tokens in one step without no leftover of bitcoins.

So essentially what you need:

  • send the specified amount of tokens from address A
  • use a minimum required amount of BTC from A, so there is ideally some left for additional sends
  • use the rest of the required amount of BTC from address B, the fee address

Is that correct?

@sashabeton
Copy link

In my case BTC's UTXO was present in listlockunspent outputs list instead of expected listunspent, and simple lockunspent true command helped me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests