REP: 3003
Title: Glyph v2 Test Vectors (CBOR + SHA256 + Envelope Payloads)
Author: C. Donnachie
Status: Draft
Type: Informational
Created: 2026-01-24
Requires: REP-3001, REP-3002
License: MIT
Original: RIP-GLYPH-0004
This document provides deterministic test vectors for:
- canonical CBOR bytes (hex)
- commit hash = SHA256(CBOR)
- example commit payload bytes (hex) for the envelope
{
"v": 2,
"type": "text",
"name": "Hello Glyph v2",
"created": 1760000000,
"content": {
"mode": "inline",
"primary": {
"path": "hello.txt",
"mime": "text/plain",
"size": 5,
"hash": {
"algo": "sha256",
"hex": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
},
"encoding": "raw",
"compression": "none"
}
},
"policy": {
"renderable": true,
"executable": false
}
}a6617602646e616d656e48656c6c6f20476c7970682076326474797065647465787466706f6c696379a26a65786563757461626c65f46a72656e64657261626c65f567636f6e74656e74a2646d6f646566696e6c696e65677072696d617279a66468617368a26368657878403263663234646261356662306133306532366538336232616335623965323965316231363165356331666137343235653733303433333632393338623938323464616c676f66736861323536646d696d656a746578742f706c61696e64706174686968656c6c6f2e7478746473697a650568656e636f64696e67637261776b636f6d7072657373696f6e646e6f6e6567637265617465641a68e77800
83c0db7e2e2baf603bfccc1897d0f9469fa21f3635da735eecdc678da96d7678
- ASCII:
gly - hex:
676c79
This is the second push after OP_3 and PUSHDATA("gly").
Layout:
V2[1] || flags[1] || commit_hash[32]
020083c0db7e2e2baf603bfccc1897d0f9469fa21f3635da735eecdc678da96d7678
Breakdown:
- V2:
02 - flags:
00 - commit_hash:
83c0db7e2e2baf603bfccc1897d0f9469fa21f3635da735eecdc678da96d7678
Script chunk sequence (conceptual):
- OP_3
- PUSHDATA(MAGIC="gly")
- PUSHDATA(canonical_metadata_bytes = CBOR hex above)
- (optional) PUSHDATA(file chunks ...)
Indexers should parse chunk #3 as canonical metadata bytes and verify it hashes to the commit hash.
53 03 676c79 4d f701 a6617602646e616d656e48656c6c6f20476c7970682076326474797065647465787466706f6c696379a26a65786563757461626c65f46a72656e64657261626c65f567636f6e74656e74a2646d6f646566696e6c696e65677072696d617279a66468617368a26368657878403263663234646261356662306133306532366538336232616335623965323965316231363165356331666137343235653733303433333632393338623938323464616c676f66736861323536646d696d656a746578742f706c61696e64706174686968656c6c6f2e7478746473697a650568656e636f64696e67637261776b636f6d7072657373696f6e646e6f6e6567637265617465641a68e77800 05 68656c6c6f
Breakdown:
53= OP_303 676c79= PUSHDATA(3 bytes, "gly")4d f701= OP_PUSHDATA2, length 503 (0x01f7)- (CBOR metadata bytes)
05 68656c6c6f= PUSHDATA(5 bytes, "hello" = file content)
6a 26 676c79 02 00 83c0db7e2e2baf603bfccc1897d0f9469fa21f3635da735eecdc678da96d7678
Breakdown:
6a= OP_RETURN26= PUSHDATA(38 bytes)676c79= MAGIC "gly"02= V200= flags (no optional fields)83c0db7e...= commit_hash (32 bytes)
{
"v": 2,
"type": "bundle",
"name": "My Game Mod",
"created": 1760000000,
"content": {
"mode": "inline",
"primary": {
"path": "manifest.json",
"mime": "application/json",
"size": 128,
"hash": {
"algo": "sha256",
"hex": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"encoding": "raw",
"compression": "none"
},
"files": [
{
"path": "data/items.dat",
"mime": "application/octet-stream",
"size": 4096,
"hash": {
"algo": "sha256",
"hex": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
},
"encoding": "raw",
"compression": "gzip"
}
]
},
"policy": { "renderable": true, "executable": false }
}<compute SHA256 of canonical CBOR encoding>
{
"v": 2,
"type": "game_item",
"name": "Radiant Sword +1",
"content": {
"mode": "inline",
"primary": {
"path": "item.json",
"mime": "application/json",
"size": 256,
"hash": {
"algo": "sha256",
"hex": "abc123def456abc123def456abc123def456abc123def456abc123def456abc1"
},
"encoding": "raw",
"compression": "none"
}
},
"policy": { "renderable": true, "executable": false },
"mutable": {
"allowed": true,
"controller": "02abc123def456abc123def456abc123def456abc123def456abc123def456abc123",
"fields": ["app.data.state"]
},
"app": {
"namespace": "rxd.game",
"schema": "game_item_v1",
"data": {
"base": {
"item_id": "sword_radiant",
"slot": "weapon",
"rarity": "rare",
"tags": ["melee"],
"stats": { "atk": 12 },
"stackable": false
},
"state": { "level": 1, "durability": 100 }
}
}
}Layout: V2[1] || flags[1] || commit_hash[32] || controller_tlv
02 02 <commit_hash_32bytes> 01 21 02abc123def456abc123def456abc123def456abc123def456abc123def456abc123
Breakdown:
02= V202= flags (has_controller = bit1)<commit_hash>= 32 bytes01= TLV type (pubkey)21= TLV length (33 bytes)02abc123...= compressed pubkey
{
"v": 1,
"type": "text",
"name": "Test",
"policy": { "renderable": true, "executable": false }
}Result: REJECT — v must be 2
{ "v": 2, "type": "text", "name": "Test" }Result: REJECT — policy is required
{
"v": 2,
"type": "text",
"name": "Test",
"content": {
"mode": "inline",
"primary": {
"path": "test.txt",
"mime": "text/plain",
"size": 5,
"hash": { "algo": "sha256", "hex": "INVALID_HEX" },
"encoding": "raw",
"compression": "none"
}
},
"policy": { "renderable": true, "executable": false }
}Result: REJECT — hash hex is not valid lowercase hexadecimal
Commit payload: 02 F0 <commit_hash>
Result: REJECT — reserved flag bits (0xF0) are non-zero
| Offset | Bytes | CBOR Type | Meaning |
|---|---|---|---|
| 0 | a6 |
map(6) | 6 key-value pairs |
| 1 | 61 76 |
text(1) "v" | key |
| 3 | 02 |
uint(2) | value |
| 4 | 64 6e616d65 |
text(4) "name" | key |
| 9 | 6e 48656c6c6f... |
text(14) "Hello Glyph v2" | value |
| ... | ... | ... | ... |
Implementers SHOULD verify their CBOR library produces identical bytes before hashing.
Deterministic test vectors are essential for verifying correct implementation of Glyph v2 encoding and hashing. Without standardized vectors, implementations may produce incompatible results.
All vectors in this document use the formats and algorithms defined in REP-3001 and REP-3002.
These test vectors are specific to Glyph v2. Glyph v1 implementations should not use these vectors.
Vectors are chosen to cover common cases (minimal metadata, bundles, mutable glyphs) as well as edge cases (invalid inputs).
See REP-3004 for indexer implementation guide and C++ examples.
Test vectors for invalid inputs (Vector 7) ensure implementations properly reject malformed data, preventing potential security issues from accepting invalid Glyphs.
This document is licensed under the MIT License.