Page MenuHomePhabricator

[Cashtab] Add function to create alias op_return outputScript
ClosedPublic

Authored by bytesofman on Apr 28 2023, 22:31.

Details

Summary

T3060

Per the updated alias spec, alias registration txs will have the following format

6a - OP_RETURN
04 - 4 bytes pushdata
2e786563 - alias protocol identifier (".xec")
00 - alias protocol version number pushed with OP_0
** - 1 byte pushdata, alias.length, in hex, e.g. '04' for a 4-byte alias registration, a value between 0x01 and 0x15
******** - n bytes, alias in hex
15 - 21 bytes of pushdata for address and address version byte
00 or 08 - marks address as p2pkh or p2sh
<hash> - address payload

A new function generateAliasOpReturnScript is added to create an OP_RETURN script matching this spec. Unit tests are added for sample registrations to p2pkh and p2sh addresses.

Test Plan
  • Review the planned stack and comment on any improvements, errors, observations
  • Review the new function and unit tests
  • npm test

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Better code commenting

cashtab/package.json
39 ↗(On Diff #40092)

I didn't realize we already had an updated-ish version of ecashaddrjs in Cashtab. We need a version that supports returning hash as a string.

Could back this upgrade out but it is backwards compatible.

back out unrelated ecashaddrjs update

Adding expected outputScript results to unit test for easier review

code commenting improvements

Fabien requested changes to this revision.May 1 2023, 10:12
Fabien added a subscriber: Fabien.
Fabien added inline comments.
cashtab/src/utils/cashMethods.js
628 ↗(On Diff #40096)

Start at 0 using minimal push, i.e. OP_0 => 0x00.
See the spec discussion in D13825.

635 ↗(On Diff #40096)

The alias version is expected to be its own push, and the alias comes after the address

This revision now requires changes to proceed.May 1 2023, 10:12

Push protocol version as own byte, add address to stack before alias

push alias and then address

Fabien requested changes to this revision.May 2 2023, 08:11
Fabien added inline comments.
cashtab/src/utils/__tests__/cashMethods.test.js
627 ↗(On Diff #40133)

If this is the output, then your code doesn't work according to the spec. The version byte is not the expected push opcode.

cashtab/src/utils/cashMethods.js
614 ↗(On Diff #40133)
620 ↗(On Diff #40133)

Can you explain or point to the bug ? I don't understand, it seems to me that you are pushing the Buffer.

632 ↗(On Diff #40133)

You are converting in hex to then decode from hex, which is a non sense.
Just read the value as an integer directly.

638 ↗(On Diff #40133)

Dito

655 ↗(On Diff #40133)

Dito (for addressVersionByte)

This revision now requires changes to proceed.May 2 2023, 08:11

Also please update the summary that refers to the previous spec version

bytesofman marked 3 inline comments as done.

responding to feedback

cashtab/src/utils/__tests__/cashMethods.test.js
627 ↗(On Diff #40133)

this is mb related to me misunderstanding the spec

6a042e7865630100077465737474776f1508d37c4c809fe9840e7bfa77b86bd47163f6fb6c60

6a

  1. A push of the 4-byte protocol identifier.

04 -> the protocol identifier will be 4 bytes
2e786563 -> the protocol identifier

  1. A push of a version number.

01 -> the version number will be 1 byte
00 -> the version number

  1. A push of the Alias.

07 -> the alias will be 7 bytes
7465737474776f -> the alias

  1. A push of a CashAddr payload. This information defines the "Alias Address".

15 -> the address version byte + address will be 21 bytes
08d37c4c809fe9840e7bfa77b86bd47163f6fb6c60 -> address version byte plus address

cashtab/src/utils/cashMethods.js
620 ↗(On Diff #40133)

This is a way to avoid adding a pushdata byte before the 6a

let script = [106];
utxolib.script.compile(script);
// 6a

vs

let script = [];
script.push(Buffer.from('6a', 'hex'));
utxolib.script.compile(script);
// 016a
632 ↗(On Diff #40133)

ok -- note that Buffer won't accept integer type, hence the array

655 ↗(On Diff #40133)

In this case, since I am pushing <addressVersionByte> and <hash> in one push, they need to both be in hex (address <hash> is already hex).

Fabien requested changes to this revision.May 2 2023, 15:28
Fabien added inline comments.
cashtab/src/utils/__tests__/cashMethods.test.js
627 ↗(On Diff #40133)

From the spec:

The version is indicated using opcode OP_0 through OP_16. For Phase 1, only OP_0 is allowed. OP_1 through OP_16 are reserved for future use.

cashtab/src/utils/cashMethods.js
680 ↗(On Diff #40143)

I thought this was restricted to a subset of ascii ? Is the check done in another place ?

620 ↗(On Diff #40133)

OK now I understand how it works from our slack conversation. Can you please add some comment to explain it as well ?

  • Raw data is untouched by the utxo-lib during the compile process
  • Each Buffer is treated as a data push and the appropriated push operators are automatically added
632 ↗(On Diff #40133)

It certainly does via the various write methods, but from the above explanation you don't what a Buffer here anyway.

655 ↗(On Diff #40133)

That's OK in this case as it avoids creating the buffer then appending the items, so it's a bit shorter for trivial complexity.

This revision now requires changes to proceed.May 2 2023, 15:28
bytesofman marked 3 inline comments as done.

Better explanation of compile behavior, push version as OP_0

cashtab/src/utils/cashMethods.js
680 ↗(On Diff #40143)

Yes, this is handled through front-end validation of user input before the user is able to create a transaction. Function is in validation.js

export const isValidAliasString = inputStr => {
    return /^[a-z0-9]+$/.test(inputStr);
};
This revision is now accepted and ready to land.May 2 2023, 16:27