Skip to content

Commit d8b6fe8

Browse files
committed
add the inscribe_generate function for the bitseed protocol
1 parent 05657e4 commit d8b6fe8

File tree

12 files changed

+216
-16
lines changed

12 files changed

+216
-16
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frameworks/bitcoin-move/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ bitcoin = { workspace = true }
3131
bs58 = { workspace = true, features = ["check"] }
3232
http = { workspace = true }
3333
tracing = { workspace = true }
34+
serde_json = { workspace = true }
35+
ciborium = { workspace = true }
3436

3537
move-binary-format = { workspace = true }
3638
move-bytecode-utils = { workspace = true }

frameworks/bitcoin-move/doc/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This is the reference documentation of the Bitcoin Move Framework.
1212
## Index
1313

1414

15+
- [`0x4::bitseed`](bitseed.md#0x4_bitseed)
1516
- [`0x4::brc20`](brc20.md#0x4_brc20)
1617
- [`0x4::genesis`](genesis.md#0x4_genesis)
1718
- [`0x4::light_client`](light_client.md#0x4_light_client)
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
<a name="0x4_bitseed"></a>
3+
4+
# Module `0x4::bitseed`
5+
6+
7+
8+
9+
10+
<pre><code><b>use</b> <a href="">0x2::wasm</a>;
11+
</code></pre>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) RoochNetwork
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
module bitcoin_move::bitseed {
5+
use std::vector;
6+
use moveos_std::wasm;
7+
8+
fun inscribe_generate(wasm_bytes: vector<u8>, deploy_args: vector<vector<u8>>,
9+
seed: vector<u8>, user_input: vector<u8>): vector<u8> {
10+
let wasm_instance = wasm::create_wasm_instance(wasm_bytes);
11+
let wasm_instance_id = wasm::get_instance_id(&wasm_instance);
12+
13+
let function_name = b"inscribe_generate";
14+
15+
let deploy_args_cbor = wasm::create_cbor_values(deploy_args);
16+
let arg = pack_inscribe_generate_args(deploy_args_cbor, seed, user_input);
17+
18+
let arg_with_length = wasm::add_length_with_data(arg);
19+
20+
let arg_list = vector::empty<vector<u8>>();
21+
vector::push_back(&mut arg_list, arg_with_length);
22+
let memory_args_list = wasm::create_memory_wasm_args(wasm_instance_id, function_name, arg_list);
23+
24+
let ret_val = wasm::execute_wasm_function(wasm_instance_id, function_name, memory_args_list);
25+
26+
let ret_data_length = wasm::read_data_length(wasm_instance_id, ret_val);
27+
let ret_data = wasm::read_data_from_heap(wasm_instance_id, (ret_val as u32) + 4, ret_data_length);
28+
29+
wasm::release_wasm_instance(wasm_instance);
30+
ret_data
31+
}
32+
33+
fun pack_inscribe_generate_args(deploy_args: vector<u8>, seed: vector<u8>, user_input: vector<u8>): vector<u8>{
34+
native_pack_inscribe_generate_args(deploy_args, b"attrs", seed, b"seed",
35+
user_input, b"user_input")
36+
}
37+
38+
native fun native_pack_inscribe_generate_args(
39+
deploy_args: vector<u8>, deploy_args_key: vector<u8>,
40+
seed: vector<u8>, seed_key: vector<u8>,
41+
user_input: vector<u8>, user_input_key: vector<u8>,
42+
): vector<u8>;
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use crate::natives::ord::bitseed::ArgsPackingGasParameters;
2+
use rooch_framework::natives::gas_parameter::native::MUL;
3+
4+
rooch_framework::natives::gas_parameter::native::define_gas_parameters_for_natives!(ArgsPackingGasParameters, "bitseed", [
5+
[.base, "from_witness.base", 100 * MUL],
6+
[.per_byte, "from_witness.base", 1000 * MUL],
7+
]);

frameworks/bitcoin-move/src/natives/gas_parameter/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
mod ord;
5+
mod bitseed;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use std::collections::VecDeque;
2+
3+
use move_binary_format::errors::PartialVMResult;
4+
use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes};
5+
use move_vm_runtime::native_functions::NativeContext;
6+
use move_vm_types::loaded_data::runtime_types::Type;
7+
use move_vm_types::natives::function::NativeResult;
8+
use move_vm_types::pop_arg;
9+
use move_vm_types::values::Value;
10+
use serde_json::Number;
11+
use serde_json::Value as JSONValue;
12+
use smallvec::smallvec;
13+
14+
use moveos_stdlib::natives::moveos_stdlib::wasm::E_CBOR_MARSHAL_FAILED;
15+
16+
#[derive(Debug, Clone)]
17+
pub struct ArgsPackingGasParameters {
18+
pub base: InternalGas,
19+
pub per_byte: InternalGasPerByte,
20+
}
21+
22+
impl ArgsPackingGasParameters {
23+
pub fn zeros() -> Self {
24+
Self {
25+
base: 0.into(),
26+
per_byte: 0.into(),
27+
}
28+
}
29+
}
30+
31+
/// Rust implementation of native_pack_inscribe_generate_args
32+
#[inline]
33+
pub(crate) fn native_pack_inscribe_generate_args(
34+
gas_params: &ArgsPackingGasParameters,
35+
_context: &mut NativeContext,
36+
_ty_args: Vec<Type>,
37+
mut args: VecDeque<Value>,
38+
) -> PartialVMResult<NativeResult> {
39+
let user_input_key = pop_arg!(args, Vec<u8>);
40+
let user_input = pop_arg!(args, Vec<u8>);
41+
let seed_key = pop_arg!(args, Vec<u8>);
42+
let seed = pop_arg!(args, Vec<u8>);
43+
let deploy_args_key = pop_arg!(args, Vec<u8>);
44+
let deploy_args = pop_arg!(args, Vec<u8>);
45+
46+
let user_input_key_string = String::from_utf8_lossy(user_input_key.as_slice()).to_string();
47+
let seed_key_string = String::from_utf8_lossy(seed_key.as_slice()).to_string();
48+
let deploy_args_key_string = String::from_utf8_lossy(deploy_args_key.as_slice()).to_string();
49+
50+
// the top level cbor map
51+
let mut buffer_map = serde_json::Map::new();
52+
53+
// attrs
54+
let mut attrs_buffer_vec = Vec::new();
55+
for byte in deploy_args.iter() {
56+
attrs_buffer_vec.push(serde_json::Value::Number(Number::from(byte.clone())));
57+
}
58+
59+
buffer_map.insert(
60+
deploy_args_key_string,
61+
serde_json::Value::Array(attrs_buffer_vec),
62+
);
63+
64+
// seed
65+
let seed_string = String::from_utf8_lossy(seed.as_slice()).to_string();
66+
buffer_map.insert(seed_key_string, serde_json::Value::String(seed_string));
67+
68+
// user_input
69+
let user_input_string = String::from_utf8_lossy(user_input.as_slice()).to_string();
70+
buffer_map.insert(
71+
user_input_key_string,
72+
serde_json::Value::String(user_input_string),
73+
);
74+
75+
// marshal the cbor map to bytes
76+
let top_buffer_map = JSONValue::Object(buffer_map);
77+
let mut top_buffer = Vec::new();
78+
match ciborium::into_writer(&top_buffer_map, &mut top_buffer) {
79+
Ok(_) => {}
80+
Err(_) => {
81+
return Ok(NativeResult::err(gas_params.base, E_CBOR_MARSHAL_FAILED));
82+
}
83+
}
84+
85+
let mut cost = gas_params.base;
86+
let total_length = user_input_key.len()
87+
+ user_input.len()
88+
+ seed_key.len()
89+
+ seed.len()
90+
+ deploy_args_key.len()
91+
+ deploy_args.len();
92+
cost += gas_params.per_byte * NumBytes::new(total_length as u64);
93+
94+
let ret = Value::vector_u8(top_buffer);
95+
Ok(NativeResult::ok(cost, smallvec![ret]))
96+
}

frameworks/bitcoin-move/src/natives/ord/mod.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) RoochNetwork
22
// SPDX-License-Identifier: Apache-2.0
33

4+
pub mod bitseed;
45
#[allow(dead_code)]
56
pub mod envelope;
67
#[allow(dead_code)]
@@ -12,6 +13,7 @@ pub mod media;
1213
#[allow(dead_code)]
1314
pub(crate) mod test;
1415

16+
use crate::natives::ord::bitseed::{native_pack_inscribe_generate_args, ArgsPackingGasParameters};
1517
use move_binary_format::errors::{PartialVMError, PartialVMResult};
1618
use move_core_types::gas_algebra::InternalGas;
1719
use move_core_types::vm_status::StatusCode;
@@ -83,21 +85,32 @@ pub(crate) fn native_from_witness(
8385
#[derive(Debug, Clone)]
8486
pub struct GasParameters {
8587
pub from_witness: FromWitnessGasParameters,
88+
pub bitseed_pack_inscribe_generate_args: ArgsPackingGasParameters,
8689
}
8790

8891
impl GasParameters {
8992
pub fn zeros() -> Self {
9093
Self {
9194
from_witness: FromWitnessGasParameters::zeros(),
95+
bitseed_pack_inscribe_generate_args: ArgsPackingGasParameters::zeros(),
9296
}
9397
}
9498
}
9599

96100
pub fn make_all(gas_params: GasParameters) -> impl Iterator<Item = (String, NativeFunction)> {
97-
let natives = [(
98-
"from_witness",
99-
make_native(gas_params.from_witness, native_from_witness),
100-
)];
101+
let natives = [
102+
(
103+
"from_witness",
104+
make_native(gas_params.from_witness, native_from_witness),
105+
),
106+
(
107+
"native_pack_inscribe_generate_args",
108+
make_native(
109+
gas_params.bitseed_pack_inscribe_generate_args,
110+
native_pack_inscribe_generate_args,
111+
),
112+
),
113+
];
101114

102115
make_module_natives(natives)
103116
}

moveos/moveos-stdlib/moveos-stdlib/doc/wasm.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161

6262

63-
<pre><code><b>public</b> <b>fun</b> <a href="wasm.md#0x2_wasm_create_cbor_values">create_cbor_values</a>(value: <a href="">vector</a>&lt;u8&gt;): <a href="">vector</a>&lt;u8&gt;
63+
<pre><code><b>public</b> <b>fun</b> <a href="wasm.md#0x2_wasm_create_cbor_values">create_cbor_values</a>(value: <a href="">vector</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;): <a href="">vector</a>&lt;u8&gt;
6464
</code></pre>
6565

6666

moveos/moveos-stdlib/moveos-stdlib/sources/wasm.move

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module moveos_std::wasm {
1212
WASMInstance {id: instance_id }
1313
}
1414

15-
public fun create_cbor_values(value: vector<u8>): vector<u8> {
15+
public fun create_cbor_values(value: vector<vector<u8>>): vector<u8> {
1616
native_create_cbor_values(value)
1717
}
1818

@@ -42,7 +42,7 @@ module moveos_std::wasm {
4242

4343
native fun native_create_wasm_instance(bytecodes: vector<u8>): u64;
4444

45-
native fun native_create_cbor_values(value: vector<u8>): vector<u8>;
45+
native fun native_create_cbor_values(value: vector<vector<u8>>): vector<u8>;
4646

4747
native fun native_add_length_with_data(value: vector<u8>): vector<u8>;
4848

moveos/moveos-stdlib/src/natives/moveos_stdlib/wasm.rs

+33-9
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ use crate::natives::helpers::{make_module_natives, make_native};
2626
const E_INSTANCE_NO_EXISTS: u64 = 1;
2727
// const E_ARG_NOT_U32: u64 = 2;
2828
const E_ARG_NOT_VECTOR_U8: u64 = 3;
29-
const E_JSON_MARSHAL_FAILED: u64 = 4;
29+
// const E_JSON_MARSHAL_FAILED: u64 = 4;
3030
const E_WASM_EXECUTION_FAILED: u64 = 5;
3131
const E_WASM_FUNCTION_NOT_FOUND: u64 = 6;
3232
const E_WASM_MEMORY_ACCESS_FAILED: u64 = 7;
33+
const E_JSON_UNMARSHAL_FAILED: u64 = 8;
34+
pub const E_CBOR_MARSHAL_FAILED: u64 = 9;
3335

3436
#[derive(Debug, Clone)]
3537
pub struct WASMCreateInstanceGasParameters {
@@ -90,18 +92,40 @@ fn native_create_cbor_values(
9092
_ty_args: Vec<Type>,
9193
mut args: VecDeque<Value>,
9294
) -> PartialVMResult<NativeResult> {
93-
let data = pop_arg!(args, Vec<u8>);
94-
let data_string = String::from_utf8_lossy(data.as_slice()).to_string();
95+
let value_list = pop_arg!(args, Vec<Value>);
9596

96-
let data_json: JSONValue = match serde_json::from_str(data_string.as_str()) {
97-
Ok(json_value) => json_value,
98-
Err(_) => {
99-
return Ok(NativeResult::err(gas_params.base, E_JSON_MARSHAL_FAILED));
97+
let mut func_args = Vec::new();
98+
for arg_value in value_list.iter() {
99+
let value = arg_value.copy_value()?;
100+
match value.value_as::<Vec<u8>>() {
101+
Ok(v) => func_args.push(String::from_utf8_lossy(v.as_slice()).to_string()),
102+
Err(_) => {
103+
return Ok(NativeResult::err(gas_params.base, E_ARG_NOT_VECTOR_U8));
104+
}
100105
}
101-
};
106+
}
102107

108+
let mut mint_args_json: Vec<JSONValue> = vec![];
109+
110+
for arg in func_args.iter() {
111+
let arg_json_opt = serde_json::from_str(arg.as_str());
112+
let arg_json: JSONValue = match arg_json_opt {
113+
Ok(v) => v,
114+
Err(_) => {
115+
return Ok(NativeResult::err(gas_params.base, E_JSON_UNMARSHAL_FAILED));
116+
}
117+
};
118+
mint_args_json.push(arg_json);
119+
}
120+
121+
let mint_args_array = JSONValue::Array(mint_args_json);
103122
let mut cbor_buffer = Vec::new();
104-
ciborium::into_writer(&data_json, &mut cbor_buffer).expect("ciborium marshal failed");
123+
match ciborium::into_writer(&mint_args_array, &mut cbor_buffer) {
124+
Ok(_) => {}
125+
Err(_) => {
126+
return Ok(NativeResult::err(gas_params.base, E_CBOR_MARSHAL_FAILED));
127+
}
128+
}
105129

106130
let ret_vec = Value::vector_u8(cbor_buffer.clone());
107131

0 commit comments

Comments
 (0)