-
Notifications
You must be signed in to change notification settings - Fork 36
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
Docs Update #307
Closed
Closed
Docs Update #307
Changes from 3 commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
44cd979
WIP - JSON clarification
rooooooooob b69a64a
docs: cbor section
rooooooooob fc80de1
add canonical cbor to wasm wrappers
rooooooooob e1793c8
SubCoin:from_base10_f32() + Config docs + Plutus builder dos + misc docs
rooooooooob 9f645c0
Merge branch 'develop' into docs-update-again
rooooooooob 9b39648
feat: add native-script verify function (#332)
hadelive 1f4d17c
Cost models update conway (#336)
rooooooooob de5e500
wasm-bindgen: upgrade to 0.2.87 and remove serde-deserialize feature …
ecioppettini 057d0fd
Add WASM getters to TransactionUnspentOutput (#341)
rooooooooob bd01b79
Add documentation + fix acronym names (#339)
rooooooooob 2f4b98f
Move RawBytesEncoding and standardize use (#340)
rooooooooob 92f98f0
add serde::Serialize/Deserialize to NetworkInfo (#342)
rooooooooob 736c94c
Governance Builders (#333)
rooooooooob 3df930c
Fix for coin/deposit merge issue (#344)
rooooooooob d03c381
Remove wasm-bindgen deps from rust (#343)
rooooooooob c8ebf5c
Add support for parsing Shelley genesis blocks (#331)
SebastienGllmt 3336a3a
SubCoin:from_base10_f32() + Config docs + Plutus builder dos + misc docs
rooooooooob f0a5456
fmt
rooooooooob File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
sidebar_position: 5 | ||
sidebar_position: 3 | ||
--- | ||
|
||
# CIP25 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
sidebar_position: 1 | ||
--- | ||
|
||
# CBOR | ||
|
||
Cardano on-chain types are stored using [CBOR](https://www.rfc-editor.org/rfc/rfc7049), a data format similar to JSON but with many more features and in binary. | ||
|
||
## Tool Interoperability | ||
|
||
Due to CBOR's flexibility it is possible that one piece of CBOR can be represented in multiple ways in the binary encoding. This causes problems when using CBOR taken on-chain or from another tool and using it with another tool. Notably, one small difference in the binary encoding of CBOR could result in hashes being totally different. e.g. metadatum hashes or transaction hashes calculated in a dApp might be different than in the wallet causing the entire transaction to be rejected by the network. | ||
|
||
CML solves this by supporting automatically every single possible CBOR encoding variation. On-chain types created by deserializing from CBOR bytes will remember these details and re-serializing will use them and result in the same CBOR bytes, unlike some other tools. | ||
|
||
## Rust | ||
|
||
On-chan types in rust can (de)serialize to/from CBOR Via the `Serialize`/`Deserialize` and `ToBytes`/`FromBytes` traits located within the `cml_core::serialize` module. | ||
|
||
Most on-chain types implement the `Serialize` and `Deserialize` traits. These traits guarantee that all CBOR encoding details are preserved upon deserialization and upon serialization it is possible to choose between canonical CBOR encoding and arbitrary encodings (the original it was decoded from). | ||
|
||
Byron-era types do not implement `Serialize`/`Deserialize` and instead implement `ToBytes`/`FromBytes`. Byron on-chain types are always in canonical CBOR so this was not necessary. | ||
|
||
The types in the `cip25` module also do not support `Serialize`/`Deserialize` in favor of `ToBytes`/`FromBytes`. The underlying metadata on-chain does and you should use the types in`cml_core::metadata` | ||
|
||
```rust | ||
use cml_core::serialization::{Serialize, Deserialize}; | ||
let canonical_cbor_hex = "825820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01"; | ||
// these all represent the following CBOR: | ||
// [ ; array of 2 elements (transaction input struct) | ||
// 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, ; bytes (tx hash) | ||
// 1 ; unsigned integer (tx index) | ||
// ] | ||
let non_canonical_cbor = [ | ||
canonical_cbor_hex, | ||
"825820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1a00000001", | ||
"9f5f48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaaff01ff", | ||
"9900025820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190001", | ||
"9b00000000000000025f41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aaff1b0000000000000001", | ||
]; | ||
for orig_cbor_hex in non_canonical_cbor { | ||
let tx_in = TransactionInput::from_cbor_bytes(&hex::decode(orig_cbor_hex).unwrap()).unwrap(); | ||
// serialize back to cbor bytes using the same cbor encoding details so it will match | ||
// the format where it came from | ||
assert_eq!(hex::encode(tx_in.to_cbor_bytes()), orig_cbor_hex); | ||
// no matter how it was created it will represent the same data and can be encoded to | ||
// canonical cbor bytes which will be the same as all of these are the same transaction input | ||
assert_eq!(hex::encode(tx_in.to_canonical_cbor_bytes()), canonical_cbor_hex); | ||
} | ||
``` | ||
|
||
## WASM | ||
|
||
All on-chain types have the traits directly exposed on each struct as the methods: | ||
* `.to_cbor_bytes()` | ||
* `.to_canonical_cbor_bytes()` | ||
* `.from_cbor_bytes()` | ||
* `.to_cbor_hex()` | ||
* `.to_canonical_cbor_hex()` | ||
* `.from_cbor_hex()` | ||
|
||
The hex ones are useful for working with CIP-30 (dApp connector). | ||
|
||
On post-Byron on-chain types this delegates to `Serialize`/`Deserialize` (see rust section) and preserve round-trip always. CIP25 and Byron types will always serialize to canonical CBOR. All on-chain data during the Byron era has to be canonical CBOR so this is not a big issue but is worth noting. | ||
|
||
```javascript | ||
let canonicalCborHex = "825820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa01"; | ||
// these all represent the following CBOR: | ||
// [ ; array of 2 elements (transaction input struct) | ||
// 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, ; bytes (tx hash) | ||
// 1 ; unsigned integer (tx index) | ||
// ] | ||
let nonCanonicalCbor = [ | ||
canonicalCborHex, | ||
"825820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1a00000001", | ||
"9f5f48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaa48aaaaaaaaaaaaaaaaff01ff", | ||
"9900025820aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa190001", | ||
"9b00000000000000025f41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aa41aaff1b0000000000000001", | ||
]; | ||
for (let origCborHex of nonCanonicalCbor) { | ||
let txIn = CML.TransactionInput.from_cbor_hex(orig_cbor_hex); | ||
// serialize back to cbor bytes using the same cbor encoding details so it will match | ||
// the format where it came from | ||
console.assert(txIn.to_cbor_hex() == origCborHex); | ||
// no matter how it was created it will represent the same data and can be encoded to | ||
// canonical cbor bytes which will be the same as all of these are the same transaction input | ||
console.assert(txIn.to_canonical_cbor_hex() == canonicalCborHex); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
sidebar_position: 5 | ||
sidebar_position: 4 | ||
--- | ||
# CIP36 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
--- | ||
sidebar_position: 2 | ||
--- | ||
|
||
# JSON | ||
|
||
## General structs | ||
|
||
All on-chain types have to/from JSON support. The vast majority is auto-generated but some have custom logic e.g. `Url`, `Ipv4`, `BigInteger`, etc. | ||
|
||
### WASM | ||
|
||
In WASM JSON conversions are exposed by `.to_json()` and `.from_json()` methods on all supported wrappers. There is also a `to_js_value()`. | ||
|
||
```javascript | ||
let txInJson = "{\"transaction_id\":\"0fba1404ed9b82b41938ba2e8bda7bec8cce813fb7e7cd7692b43caa76fe891c\",\"index\":3}"; | ||
|
||
let txIn = CML.TransactionInput.from_json(txInJson); | ||
|
||
console.log(`txIn JSON: ${txIn.to_json()}`); | ||
``` | ||
|
||
### Rust | ||
|
||
JSON conversions are exposed in rust via the [`serde::Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and [`serde::Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) traits together with `serde_json`. | ||
|
||
example: | ||
```rust | ||
let tx_in_json = "{\"transaction_id\":\"0fba1404ed9b82b41938ba2e8bda7bec8cce813fb7e7cd7692b43caa76fe891c\",\"index\":3}"; | ||
|
||
// from JSON using serde_json::from_str() - note the type annotations | ||
let tx_in: TransactionInput = serde_json::from_str(tx_in_json).unwrap(); | ||
|
||
// to JSON using serde_json::to_string() - use to_string_pretty() if you want more human-readable formatting | ||
println!("tx_in JSON: {}", serde_json::to_string(&tx_in).unwrap()); | ||
``` | ||
|
||
## Metadata | ||
|
||
Metadata, on top of the generic API mentioned above, has specific JSON functionality for compatability with cardano-node. | ||
|
||
There are three formats on `MetadataJsonSchema`. `NoConversions` is the stricted, stricter than cardano-node and only converts when there are no implicit conversions at all. `BasicConversions` is the node's `TxMetadataJsonNoSchema` and `DetailedSchema` its `TxMetadataJsonDetailedSchema`. See `MetadataJsonSchema` for more info on the schema. | ||
|
||
```javascript | ||
let basic_json = "{\"0x8badf00d\": \"0xdeadbeef\",\"9\": 5,\"obj\": {\"a\":[{\"5\": 2},{}]}}"; | ||
let metadatum = CML.encode_json_str_to_metadatum(basic_json, CML.MetadataJsonSchema.BasicConversions); | ||
console.log(`detailed json: ${CML.decode_metadatum_to_json_str(metadatum, CML.MetadataJsonSchema.DetailedSchema)}`); | ||
// OUTPUT: | ||
// detailed json: {"map":[{"k":{"bytes":"8badf00d"},"v":{"bytes":"deadbeef"}},{"k":{"int":9},"v":{"int":5}},{"k":{"string":"obj"},"v":{"map":[{"k":{"string":"a"},"v":{"list":[{"map":[{"k":{"int":5},"v":{"int":2}}]},{"map":[]}]}}]}}]} | ||
``` | ||
|
||
## Plutus Datums | ||
|
||
Plutus datums also have additional cardano-node JSON support. Remember that Plutus has no String datum so the strings there will be converted to utf8 bytes. See `CardanoNodePlutusDatumSchema` for more info on the schema. | ||
|
||
```javascript | ||
let basic_json = "{ \"100\": [ { \"x\": \"0\", \"y\": 1 } ], \"foo\": \"0x0000baadf00d0000cafed00d0000deadbeef0000\" }"; | ||
let datum = CML.encode_json_str_to_plutus_datum(basic_json, CML.CardanoNodePlutusDatumSchema.BasicConversions); | ||
console.log(`detailed json: ${CML.decode_plutus_datum_to_json_str(datum, CML.CardanoNodePlutusDatumSchema.DetailedSchema, | ||
)}`); | ||
// OUTPUT: | ||
// detailed json: {"map":[{"k":{"int":100},"v":{"list":[{"map":[{"k":{"bytes":"78"},"v":{"bytes":"30"}},{"k":{"bytes":"79"},"v":{"int":1}}]}]}},{"k":{"bytes":"666f6f"},"v":{"bytes":"0000baadf00d0000cafed00d0000deadbeef0000"}}]} | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this to all the types that support preserve-encodings/etc as we expose it in rust and it can't hurt to expose it. I used it in the cbor docs example.
One small possible inconsistency is that it's not added to the byron/cip25 types as we can't guarantee anything implementing
cbor_event::Serialize
will do it canonically or not. The comment forto_cbor_bytes()
on those types does mention that the format may or may not be canonical.