22
22
//! Non-Inflatable Assets (NIA) schema implementing RGB20 fungible assets
23
23
//! interface.
24
24
25
- use aluvm:: isa:: Instr ;
26
- use aluvm:: isa:: opcodes:: { INSTR_PUTA , INSTR_TEST } ;
27
25
use aluvm:: library:: { Lib , LibSite } ;
28
26
use amplify:: confinement:: Confined ;
29
27
use bp:: dbc:: Method ;
@@ -38,7 +36,6 @@ use rgbstd::schema::{
38
36
GenesisSchema , GlobalStateSchema , Occurrences , OwnedStateSchema , Schema , TransitionSchema ,
39
37
} ;
40
38
use rgbstd:: validation:: Scripts ;
41
- use rgbstd:: vm:: RgbIsa ;
42
39
use rgbstd:: { Identity , rgbasm} ;
43
40
use strict_encoding:: InvalidRString ;
44
41
use strict_types:: TypeSystem ;
@@ -48,33 +45,78 @@ use crate::{
48
45
OS_ASSET , TS_TRANSFER ,
49
46
} ;
50
47
51
- pub ( crate ) fn nia_lib ( ) -> Lib {
52
- let code = rgbasm ! {
53
- // SUBROUTINE Transfer validation
54
- // Set errno
55
- put a8[ 0 ] , ERRNO_NON_EQUAL_IN_OUT ;
56
- // Checking that the sum of pedersen commitments in inputs is equal to the sum in outputs.
57
- // ..................
58
- test;
59
- ret;
48
+ pub ( crate ) fn util_lib ( ) -> Lib {
49
+ rgbasm ! {
50
+ // SUBROUTINE Compute sum of inputs
51
+ // Input: a16[16] - state to compute
52
+ // Output: a64[16] - sum
53
+ // Uses: a16[0] - counter, a16[10] - zero constant, a64[0] - extracted amounts
54
+ // Fails: on sum overflow or invalid state (should not happen)
55
+ // St0: unmodified if not fails
56
+ put a16[ 10 ] , 0 ; // zero constant
57
+ put a64[ 16 ] , 0 ; // init sum with 0
58
+ cn. i a16[ 0 ] , a16[ 16 ] ; // count state
59
+ dec a16[ 0 ] ; // counter = len - 1
60
+ /**/ ld. i s16[ 0 ] , a16[ 16 ] , a16[ 0 ] ; // load state
61
+ extr s16[ 4 ] , a64[ 0 ] , a16[ 10 ] ; // extract 64 bits
62
+ test; // fail if state is absent or invalid
63
+ add. uc a64[ 16 ] , a64[ 0 ] ; // add amount to the sum
64
+ test; // fail on sum overflow
65
+ dec a16[ 0 ] ; // dec counter
66
+ jif 0 /**/ ; // repeat for all assignments
67
+ inv st0; // reset status flag
68
+ ret; // finish
60
69
70
+ // SUBROUTINE Compute sum of outputs
71
+ // Input: a16[16] - state to compute
72
+ // Output: a64[17] - sum
73
+ // Uses: a16[0] - counter, a16[10] - zero constant, a64[0] - extracted amounts
74
+ // Fails: on sum overflow or invalid state (should not happen)
75
+ // St0: unmodified if not fails
76
+ put a16[ 10 ] , 0 ; // zero constant
77
+ put a64[ 17 ] , 0 ; // init sum with 0
78
+ cn. o a16[ 0 ] , a16[ 16 ] ; // count state
79
+ dec a16[ 0 ] ; // counter = len - 1
80
+ /**/ ld. o s16[ 0 ] , a16[ 16 ] , a16[ 0 ] ; // load state
81
+ extr s16[ 4 ] , a64[ 0 ] , a16[ 10 ] ; // extract 64 bits
82
+ test; // fail if state is absent or invalid
83
+ add. uc a64[ 17 ] , a64[ 0 ] ; // add amount to the sum
84
+ test; // fail on sum overflow
85
+ dec a16[ 0 ] ; // dec counter
86
+ jif 0 /**/ ; // repeat for all assignments
87
+ inv st0; // reset status flag
88
+ ret; // finish
89
+ }
90
+ }
91
+
92
+ pub ( crate ) fn nia_lib ( ) -> Lib {
93
+ let util = util_lib ( ) . id ( ) ;
94
+ const ISSUED : u16 = GS_ISSUED_SUPPLY . to_u16 ( ) ;
95
+ const DISTRIBUTED : u16 = OS_ASSET . to_u16 ( ) ;
96
+ rgbasm ! {
61
97
// SUBROUTINE Genesis validation
62
- // Checking pedersen commitments against reported amount of issued assets present in the
63
- // global state.
64
- put a8[ 0 ] , ERRNO_ISSUED_MISMATCH ;
65
- put a8[ 1 ] , 0 ;
66
- put a16[ 0 ] , 0 ;
67
- // Read global state into s16[0]
68
- ldg GS_ISSUED_SUPPLY , a8[ 1 ] , s16[ 0 ] ;
69
- // Extract 64 bits from the beginning of s16[0] into a64[1]
70
- // NB: if the global state is invalid, we will fail here and fail the validation
71
- extr s16[ 0 ] , a64[ 0 ] , a16[ 0 ] ;
72
- // verify sum of pedersen commitments for assignments against a64[0] value
73
- // ..................
74
- test;
75
- ret;
76
- } ;
77
- Lib :: assemble :: < Instr < RgbIsa < MemContract > > > ( & code) . expect ( "wrong non-inflatable asset script" )
98
+ put a16[ 0 ] , ISSUED ; // global state to load
99
+ ld. g s16[ 3 ] , a16[ 16 ] , a16[ 0 ] ; // load reported issued amount
100
+ put a16[ 10 ] , 0 ; // zero offset
101
+ extr s16[ 3 ] , a64[ 15 ] , a16[ 10 ] ; // a64[15] <- GS_ISSUED_SUPPLY
102
+ test; // fail if state is absent or invalid
103
+
104
+ put a16[ 16 ] , DISTRIBUTED ; // owned state to load
105
+ call 0x00 @ util; // a64[17] <- sum of OS_ASSET allocations
106
+ put a8[ 0 ] , ERRNO_ISSUED_MISMATCH ; // set errno to return if we fail
107
+ eq. n a64[ 15 ] , a64[ 17 ] ; // check if ISSUED =? sum(DISTRIBUTED)
108
+ test; // fail if not
109
+ ret; // complete
110
+
111
+ // SUBROUTINE Transfer validation
112
+ put a16[ 16 ] , DISTRIBUTED ; // owned state to load
113
+ call 0x00 @ util; // a64[16] <- sum of inputs
114
+ call 0x21 @ util; // a64[17] <- sum of outputs
115
+ put a8[ 0 ] , ERRNO_NON_EQUAL_IN_OUT ; // set errno to return if we fail
116
+ eq. n a64[ 16 ] , a64[ 17 ] ; // check if sum(inputs) =? sum(outputs)
117
+ test; // fail if not
118
+ ret; // complete
119
+ }
78
120
}
79
121
pub ( crate ) const FN_NIA_GENESIS_OFFSET : u16 = 4 + 3 + 2 - 3 ;
80
122
pub ( crate ) const FN_NIA_TRANSFER_OFFSET : u16 = 0 ;
@@ -84,10 +126,6 @@ fn nia_schema() -> Schema {
84
126
85
127
let alu_lib = nia_lib ( ) ;
86
128
let alu_id = alu_lib. id ( ) ;
87
- assert_eq ! ( alu_lib. code. as_ref( ) [ FN_NIA_TRANSFER_OFFSET as usize + 4 ] , INSTR_TEST ) ;
88
- assert_eq ! ( alu_lib. code. as_ref( ) [ FN_NIA_GENESIS_OFFSET as usize ] , INSTR_PUTA ) ;
89
- assert_eq ! ( alu_lib. code. as_ref( ) [ FN_NIA_GENESIS_OFFSET as usize + 4 ] , INSTR_PUTA ) ;
90
- assert_eq ! ( alu_lib. code. as_ref( ) [ FN_NIA_GENESIS_OFFSET as usize + 8 ] , INSTR_PUTA ) ;
91
129
92
130
Schema {
93
131
ffv : zero ! ( ) ,
@@ -187,8 +225,9 @@ impl IssuerWrapper for NonInflatableAsset {
187
225
fn types ( ) -> TypeSystem { StandardTypes :: with ( Self :: FEATURES . stl ( ) ) . type_system ( ) }
188
226
189
227
fn scripts ( ) -> Scripts {
228
+ let util = util_lib ( ) ;
190
229
let lib = nia_lib ( ) ;
191
- Confined :: from_checked ( bmap ! { lib. id( ) => lib } )
230
+ Confined :: from_checked ( bmap ! { lib. id( ) => lib, util . id ( ) => util } )
192
231
}
193
232
}
194
233
@@ -221,10 +260,16 @@ mod test {
221
260
use ifaces:: stl:: * ;
222
261
use rgbstd:: containers:: { BuilderSeal , ConsignmentExt } ;
223
262
use rgbstd:: interface:: * ;
224
- use rgbstd:: * ;
263
+ use rgbstd:: { disassemble , * } ;
225
264
226
265
use super :: * ;
227
266
267
+ #[ test]
268
+ fn lib_check ( ) {
269
+ let util = util_lib ( ) ;
270
+ println ! ( "{}" , disassemble( & util) ) ;
271
+ }
272
+
228
273
#[ test]
229
274
fn iimpl_check ( ) {
230
275
let iface = NonInflatableAsset :: FEATURES . iface ( ) ;
@@ -282,7 +327,7 @@ mod test {
282
327
283
328
assert_eq ! (
284
329
contract. contract_id( ) . to_string( ) ,
285
- s!( "rgb:pOIzGFyQ-mA!yQq2-QH8vB5!-5fAplY!-x2lW!vz-JHDbYPg " )
330
+ s!( "rgb:vGAyeGF9-bPAAV8T-w1V46jM-Iz7TW7K-QzZBzcf-RMuzznw " )
286
331
) ;
287
332
}
288
333
}
0 commit comments