RGB-WG / rgb-core

RGB Core Library: consensus validation for private & scalable client-validated smart contracts on Bitcoin & Lightning
https://spec.rgb.tech
Apache License 2.0
207 stars 52 forks source link

ContractId round-trip fails for some values #209

Closed nicbus closed 4 months ago

nicbus commented 8 months ago

Some values come up different after a ContractId round-trip.

By round-trip I mean:

Here's an example:

use rgbstd::contract::ContractId;
use std::str::FromStr;

fn main() {
    let contract_id = ContractId::copy_from_slice([0u8; 32]).unwrap();

    let contract_id_string = contract_id.to_string();
    println!("contract ID string: {contract_id_string}");

    let result = ContractId::from_str(&contract_id_string);
    println!("contract ID result: {result:?}");
}

This outputs:

contract ID string: rgb:1111111-111111111-111111111-11111112k-9zwp
contract ID result: Err(Unparsable("rgb:1111111-111111111-111111111-11111112k-9zwp"))

The same error is returned by version 0.10.9 (using from_slice instead of copy_from_slice).

dr-orlovsky commented 7 months ago

Ok, I have finally figured out what's going on.

It is the only zero string which has significantly shorter Base58 encoding (32 chars instead of 43/44), so it doesn't has a valid chunking and fails to parse.

The issue is not trivial to solve: we need to refactor all the way the chunking works. For v0.11 I think the better way is to leave the things as they are: contract ids containing all-0 (or starting with at least 16 initial zeros to make length short enough to fail chunking) are all invalid anyway and can't be generated in a real-world scenarious.

nicbus commented 7 months ago

I agree there's no urgency in fixing this.

dr-orlovsky commented 5 months ago

After many attempts to fix it I was able to find an ultimate solution: switch from Base58 to Base64.

Base64 has constant size for a given source binary data - unlike Base58. The only disadvantage is the use of "/" and "-" symbols in standard encoding; but I did a modification to use "@" and "$" instead, and it seems to be working great.

I played with it in ssi for identities and signatures (which we will use in RGB as well) and developed a dedicated baid64 crate to support URL prefixes, parsing, mnemonics etc, like we had in Baid58.

Switching to it in all develop branches and will see how it will go.

yanganto commented 5 months ago

Hi @dr-orlovsky,

May I try this? It is not an urgent issue, I can take this chance to learn more, go through the Contract stuff, and make more test cases.

dr-orlovsky commented 4 months ago

Fixed by moving in beta-6 to baid64 encoding instead of baid58