Bitcoin AnySigner Error: Unable to Sign Transactions with OP_RETURN Over 80 Bytes
ronaldoguedess opened this issue · comments
Issue Description:
Bitcoin AnySigner encounters an error when attempting to sign a transaction with an OP_RETURN data exceeding 80 bytes. The OP_RETURN data I need for my transaction is 136 bytes long. While reducing it to 80 characters resolves the issue, it doesn't meet my requirements.
Background:
Bitcoin allows OP_RETURN data lengths exceeding 80 bytes, as evidenced by this transaction here, which contains 124 bytes of OP_RETURN data.
Code Snippet:
//...
val opReturnData = "D6037B019c86c912963CBAe893Db3f8DB1a471B7025F0b1a82749cb4E2278EC87F8BF6B618dC71a8bffE26BF9Fe82e05d011f9B2B4Fc6fC9DB6F4d62E400".toByteArray(Charsets.UTF_8)
input.outputOpReturn = ByteString.copyFrom(opReturnData)
//PLAN
val plan = AnySigner.plan(input.build(), CoinType.BITCOIN, Bitcoin.TransactionPlan.parser())
Log.e("xxxxxxxxxxxxx", "Planned fee: ${plan.fee} amount: ${plan.amount} avail_amount: ${plan.availableAmount} change: ${plan.change}")
input.plan = plan
input.amount = plan.amount
//SIGN TX
val output = AnySigner.sign(input.build(), CoinType.BITCOIN, Bitcoin.SigningOutput.parser())
val encoded = output.encoded
val signedTransaction = Numeric.toHexString(encoded.toByteArray()).substring(2)
assert(output.error == Common.SigningError.OK)
Expected Behavior:
Bitcoin AnySigner should be able to handle OP_RETURN data exceeding 80 bytes without errors, as per Bitcoin's protocol specifications.
Steps to Reproduce:
- Create a transaction with an OP_RETURN data length exceeding 80 bytes.
- Attempt to sign the transaction using Bitcoin AnySigner.
- Observe the error encountered due to the OP_RETURN data length.
"java.lang.AssertionError: Assertion failed | kotlin.Unit"
Additional Information:
Bitcoin transactions with OP_RETURN data lengths over 80 bytes are valid, and it's possible to check it on this OP_RETURN:
https://blockchair.com/bitcoin/testnet/address/d-449949f1579c08d6e01d45c6bd1e2858
Ensuring compatibility with OP_RETURN data lengths beyond 80 bytes is crucial for various use cases requiring larger data payloads.
Note: This issue is hindering the functionality required for specific transaction types and use cases, necessitating support for OP_RETURN data lengths exceeding 80 bytes in Bitcoin AnySigner.
Hi @ronaldoguedess, the OP_RETURN
data limit in the Bitcoin network is currently 80 bytes. This limit is enforced by a consensus rule.
https://www.talkcrypto.org/blog/2016/12/30/op_return-40-to-80-bytes/
I see the only 603c2bd11b048002e00d3527cfa2349f79b5efe724f37a57442030fcdd86caa6 transaction in the d-449949f1579c08d6e01d45c6bd1e2858 address history.
Please note that the mentioned transaction has an OP_RETURN
output with 62 pushed bytes, however, its hexadecimal representation equates to 124 bytes.
OMG, you're absolutely right @satoshiotomakan! The issue stemmed from sending UTF8 data. The solution lies in converting it to hex Bytes rather than converting it directly to a UTF8 byte array.
This is how I solve the problem, it could help someone.
fun String.toHexBytes(): ByteArray {
return Numeric.hexStringToByteArray(this)
}
// OP_RETURN OUTPUT
val opReturnData = "D6037B019c86c912963CBAe893Db3f8DB1a471B7025F0b1a82749cb4E2278EC87F8BF6B618dC71a8bffE26BF9Fe82e05d011f9B2B4Fc6fC9DB6F4d62E400".toHexBytes()
input.outputOpReturn = ByteString.copyFrom(opReturnData)
Using UTF-8 encoding, an Ethereum address is considered to be 40 bytes, whereas using hexadecimal encoding reduces it to just 20 bytes. Quite a significant difference!
I hope it helps someone. Bye.