Skip to content
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

refact dao #70

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions examples/dao_deposit_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use ckb_sdk::{
transaction::{
builder::{CkbTransactionBuilder, SimpleTransactionBuilder},
handler::{dao, HandlerContexts},
input::InputIterator,
signer::{SignContexts, TransactionSigner},
TransactionBuilderConfiguration,
},
Address, CkbRpcClient, NetworkInfo,
};
use ckb_types::h256;
use std::{error::Error as StdErr, str::FromStr};

fn main() -> Result<(), Box<dyn StdErr>> {
let network_info = NetworkInfo::testnet();
let sender = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2qf8keemy2p5uu0g0gn8cd4ju23s5269qk8rg4r")?;
let receiver=Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqv5dsed9par23x4g58seaw58j3ym5ml2hs8ztche")?;

let configuration = TransactionBuilderConfiguration::new_with_network(network_info.clone())?;

let iterator = InputIterator::new(vec![(&sender).into()], configuration.network_info());
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);

let context = dao::DepositContext::new((&receiver).into(), 510_0000_0000u64);
let mut contexts = HandlerContexts::default();
contexts.add_context(Box::new(context) as Box<_>);

builder.set_change_lock((&sender).into());
let mut tx_with_groups = builder.build(&mut contexts)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let private_keys = vec![h256!(
"0x6c9ed03816e3111e49384b8d180174ad08e29feb1393ea1b51cef1c505d4e36a"
)];
TransactionSigner::new(&network_info).sign_transaction(
&mut tx_with_groups,
&SignContexts::new_sighash_h256(private_keys)?,
)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let tx_hash = CkbRpcClient::new(network_info.url.as_str())
.send_transaction(json_tx.inner, None)
.expect("send transaction");
// example tx: 8b7ab7770c821fa8dc70738d5d6ef43da46706541c258b9a02edf66948039798
println!(">>> tx {} sent! <<<", tx_hash);

Ok(())
}
61 changes: 61 additions & 0 deletions examples/dao_withdraw_phrase1_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use ckb_sdk::{
transaction::{
builder::{CkbTransactionBuilder, SimpleTransactionBuilder},
handler::{dao, HandlerContexts},
input::InputIterator,
signer::{SignContexts, TransactionSigner},
TransactionBuilderConfiguration,
},
Address, CkbRpcClient, NetworkInfo,
};
use ckb_types::h256;
use std::{error::Error as StdErr, str::FromStr};

fn main() -> Result<(), Box<dyn StdErr>> {
let network_info = NetworkInfo::testnet();
let sender = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2qf8keemy2p5uu0g0gn8cd4ju23s5269qk8rg4r")?;

let configuration = TransactionBuilderConfiguration::new_with_network(network_info.clone())?;

let iterator = InputIterator::new(vec![(&sender).into()], configuration.network_info());
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);

let mut context = dao::WithdrawPhrase1Context::new(network_info.url.clone());
let input_outpoint = serde_json::from_str::<ckb_jsonrpc_types::OutPoint>(
r#"
{
"tx_hash": "0x2aba579894cdf5f6c4afd3ada52792c4405fe6ba64d05226fb63fa5c1ec6f666",
"index": "0x0"
}
"#,
)
.unwrap();
context.add_input_outpoint(input_outpoint.into(), None);
let mut contexts = HandlerContexts::default();
contexts.add_context(Box::new(context) as Box<_>);

builder.set_change_lock((&sender).into());
let mut tx_with_groups = builder.build(&mut contexts)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let private_keys = vec![h256!(
"0x6c9ed03816e3111e49384b8d180174ad08e29feb1393ea1b51cef1c505d4e36a"
)];
TransactionSigner::new(&network_info).sign_transaction(
&mut tx_with_groups,
&SignContexts::new_sighash_h256(private_keys)?,
)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let tx_hash = CkbRpcClient::new(network_info.url.as_str())
.send_transaction(json_tx.inner, None)
.expect("send transaction");
// example tx: b615b9cbb566af18dd2d860836b89e07a86dfcc7af510595dcb404f1b19e6d7e
println!(">>> tx {} sent! <<<", tx_hash);

Ok(())
}
61 changes: 61 additions & 0 deletions examples/dao_withdraw_phrase2_example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use ckb_sdk::{
transaction::{
builder::{CkbTransactionBuilder, SimpleTransactionBuilder},
handler::{dao, HandlerContexts},
input::InputIterator,
signer::{SignContexts, TransactionSigner},
TransactionBuilderConfiguration,
},
Address, CkbRpcClient, NetworkInfo,
};
use ckb_types::h256;
use std::{error::Error as StdErr, str::FromStr};

fn main() -> Result<(), Box<dyn StdErr>> {
let network_info = NetworkInfo::testnet();
let sender = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2qf8keemy2p5uu0g0gn8cd4ju23s5269qk8rg4r")?;

let configuration = TransactionBuilderConfiguration::new_with_network(network_info.clone())?;

let iterator = InputIterator::new(vec![(&sender).into()], configuration.network_info());
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);

let input_outpoint = serde_json::from_str::<ckb_jsonrpc_types::OutPoint>(
r#"
{
"tx_hash": "0x770f930ed3bf35664cb6a112edce3287712f0613c74c1f1176e099ee51268489",
"index": "0x0"
}
"#,
)
.unwrap();
let context =
dao::WithdrawPhrase2Context::new(vec![input_outpoint.into()], network_info.url.clone());
let mut contexts = HandlerContexts::default();
contexts.add_context(Box::new(context) as Box<_>);

builder.set_change_lock((&sender).into());
let mut tx_with_groups = builder.build(&mut contexts)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let private_keys = vec![h256!(
"0x6c9ed03816e3111e49384b8d180174ad08e29feb1393ea1b51cef1c505d4e36a"
)];
TransactionSigner::new(&network_info).sign_transaction(
&mut tx_with_groups,
&SignContexts::new_sighash_h256(private_keys)?,
)?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

let tx_hash = CkbRpcClient::new(network_info.url.as_str())
.send_transaction(json_tx.inner, None)
.expect("send transaction");
// example tx: 0xaae93c573848a632f06f01c7c444c90aa490253f35b4212d147882266960a267
println!(">>> tx {} sent! <<<", tx_hash);

Ok(())
}
2 changes: 1 addition & 1 deletion examples/send_ckb_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn main() -> Result<(), Box<dyn StdErr>> {
let addr = Address::from_str(sender)?;
builder.add_output_from_addr(&receiver, Capacity::shannons(510_0000_0000u64));
builder.set_change_addr(&addr);
let mut tx_with_groups = builder.build(&Default::default())?;
let mut tx_with_groups = builder.build(&mut Default::default())?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());
Expand Down
2 changes: 1 addition & 1 deletion examples/send_ckb_multisig_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() -> Result<(), Box<dyn StdErr>> {
builder.add_output_from_addr(&addr, Capacity::shannons(501_0000_0000u64));
builder.set_change_addr(&sender_addr);
let mut tx_with_groups =
builder.build(&HandlerContexts::new_multisig(multisig_config.clone()))?;
builder.build(&mut HandlerContexts::new_multisig(multisig_config.clone()))?;

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());
Expand Down
66 changes: 60 additions & 6 deletions src/core/advanced_builders.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use ckb_types::{constants, core, packed, prelude::*};
use ckb_types::{
constants, core,
packed::{self, WitnessArgs},
prelude::*,
};
use derive_getters::Getters;

/// An advanced builder for [`TransactionView`].
Expand Down Expand Up @@ -122,7 +126,7 @@ macro_rules! def_setter_for_vector {
def_setter_for_vector!(packed, $field, $type, $func_push, $func_extend, $func_set);
};
(set_i, $field:ident, $type:ident, $func_push:ident, $func_extend:ident, $func_set:ident, $func_set_i: ident) => {
def_setter_for_vector!(packed, $field, $type, $func_push, $func_extend, $func_set);
def_setter_for_vector!($field, $type, $func_push, $func_extend, $func_set);

pub fn $func_set_i(&mut self, i: usize, v: packed::$type) -> &mut Self {
self.$field[i] = v;
Expand All @@ -138,11 +142,12 @@ macro_rules! def_dedup_setter_for_vector {
$comment_push:expr, $comment_extend:expr,
) => {
#[doc = $comment_push]
pub fn $func_push(&mut self, v: $prefix::$type) -> &mut Self {
if !self.$field.contains(&v) {
self.$field.push(v);
pub fn $func_push(&mut self, v: $prefix::$type) -> usize {
if let Some(idx) = self.$field.iter().position(|x| x == &v) {
return idx;
}
self
self.$field.push(v);
self.$field.len() - 1
}
#[doc = $comment_extend]
pub fn $func_extend<T>(&mut self, v: T) -> &mut Self
Expand Down Expand Up @@ -221,6 +226,46 @@ impl TransactionBuilder {
set_outputs_data
);

fn get_witness_obj(&self, i: usize) -> WitnessArgs {
let witness_data = self.witnesses[i].raw_data();
if witness_data.is_empty() {
WitnessArgs::default()
} else {
WitnessArgs::from_slice(witness_data.as_ref()).unwrap()
}
}
pub fn set_witness_lock(&mut self, i: usize, v: Option<bytes::Bytes>) -> &mut Self {
let current_witness = self.get_witness_obj(i);
self.witnesses[i] = current_witness
.as_builder()
.lock(v.pack())
.build()
.as_bytes()
.pack();
self
}

pub fn set_witness_input(&mut self, i: usize, v: Option<bytes::Bytes>) -> &mut Self {
self.witnesses[i] = self
.get_witness_obj(i)
.as_builder()
.input_type(v.pack())
.build()
.as_bytes()
.pack();
self
}

pub fn set_witness_output(&mut self, i: usize, v: Option<bytes::Bytes>) -> &mut Self {
self.witnesses[i] = self
.get_witness_obj(i)
.as_builder()
.output_type(v.pack())
.build()
.as_bytes()
.pack();
self
}
/// Converts into [`TransactionView`](struct.TransactionView.html).
pub fn build(self) -> core::TransactionView {
let Self {
Expand All @@ -247,4 +292,13 @@ impl TransactionBuilder {

tx.into_view()
}

pub(crate) fn set_input_since(&mut self, i: usize, since: u64) -> &mut Self {
self.inputs[i] = self.inputs[i]
.clone()
.as_builder()
.since(since.pack())
.build();
self
}
}
12 changes: 9 additions & 3 deletions src/tests/transaction/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ fn test_transfer_from_sighash() {
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);
builder.add_output(output.clone(), ckb_types::packed::Bytes::default());
builder.set_change_lock(sender.clone());
let mut tx_with_groups = builder.build(&Default::default()).expect("build failed");
let mut tx_with_groups = builder
.build(&mut Default::default())
.expect("build failed");

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());
Expand Down Expand Up @@ -106,7 +108,9 @@ fn test_transfer_from_sighash_samll_to_fee() {
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);
builder.add_output(output.clone(), ckb_types::packed::Bytes::default());
builder.set_change_lock(sender.clone());
let mut tx_with_groups = builder.build(&Default::default()).expect("build failed");
let mut tx_with_groups = builder
.build(&mut Default::default())
.expect("build failed");

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());
Expand Down Expand Up @@ -167,7 +171,9 @@ fn test_transfer_from_sighash_samll_to_receiver() {
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);
builder.add_output(output, ckb_types::packed::Bytes::default());
builder.set_change_lock(sender.clone());
let mut tx_with_groups = builder.build(&Default::default()).expect("build failed");
let mut tx_with_groups = builder
.build(&mut Default::default())
.expect("build failed");

let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());
Expand Down
Loading