forked from kimsk/chia-piggybank
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspend_coin_sim.py
111 lines (90 loc) · 3.6 KB
/
spend_coin_sim.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import asyncio
import utils
from blspy import (PrivateKey, AugSchemeMPL, G2Element)
from cdv.test import Network, SmartCoinWrapper, Wallet
from cdv.util.load_clvm import load_clvm
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.types.blockchain_format.program import Program
from chia.types.coin_spend import CoinSpend
from chia.types.condition_opcodes import ConditionOpcode
from chia.types.spend_bundle import SpendBundle
from chia.util.hash import std_hash
from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import DEFAULT_HIDDEN_PUZZLE_HASH, calculate_synthetic_secret_key, puzzle_for_public_key_and_hidden_puzzle_hash
network: Network = asyncio.run(Network.create())
asyncio.run(network.farm_block())
alice: Wallet = network.make_wallet("alice")
bob: Wallet = network.make_wallet("bob")
asyncio.run(network.farm_block(farmer=alice))
print(f'alice balance:\t{alice.balance()}')
print(f'bob balance:\t{bob.balance()}')
alice_coins = alice.usable_coins
print(f'alice coins:')
for k, c in alice_coins.items():
print(k)
utils.print_json(c.to_json_dict())
# spend standard transaction coin
# alice sends 1 million mojos to bob
amt = 1_000_000
alice_coin = asyncio.run(alice.choose_coin(amt))
assert alice_coin != None
print(f'alice coin:\t{alice_coin}')
# conditions provided by wallet
condition_args = [
[ConditionOpcode.CREATE_COIN, bob.puzzle_hash, amt],
[ConditionOpcode.CREATE_COIN, alice.puzzle_hash, alice_coin.amount - amt],
]
delegated_puzzle_solution = Program.to((1, condition_args))
# calculate synthetic_sk to sign the spend
synthetic_sk: PrivateKey = calculate_synthetic_secret_key(
alice.sk_,
DEFAULT_HIDDEN_PUZZLE_HASH
)
# https://github.com/Chia-Network/chia-blockchain/blob/main/chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clvm
# (synthetic_public_key original_public_key delegated_puzzle solution)
# synthetic_public_key is curried in
# original_public_key is ()
# delegated_puzzle is (1 (CREATE_COIN bob amt) (CREATE_COIN alice change))
# solution is ()
solution = Program.to([[], delegated_puzzle_solution, []])
# coins can be unlocked by signing a delegated puzzle and its solution
sig = AugSchemeMPL.sign(synthetic_sk,
(
delegated_puzzle_solution.get_tree_hash()
+ alice_coin.name()
+ DEFAULT_CONSTANTS.AGG_SIG_ME_ADDITIONAL_DATA
)
)
alice_puzzle = puzzle_for_public_key_and_hidden_puzzle_hash(
alice.pk(), DEFAULT_HIDDEN_PUZZLE_HASH
)
print(f'alice puzzle: {alice_puzzle}')
# all puzzle hashes have to be the same
print(f'alice_puzzle_hash:\t{alice_puzzle.get_tree_hash()}')
print(f'alice.puzzle_hash:\t{alice.puzzle.get_tree_hash()}')
print(f'alice_coin.puzzle_hash:\t{alice_coin.puzzle_hash}')
assert alice_puzzle.get_tree_hash() == alice_coin.puzzle_hash
assert alice.puzzle.get_tree_hash() == alice_coin.puzzle_hash
spend_bundle = SpendBundle(
[
CoinSpend(
alice_coin.as_coin(),
alice.puzzle, # p2_delegated_puzzle_or_hidden_puzzle
solution,
)
],
sig,
)
asyncio.run(network.push_tx(spend_bundle))
print(f'alice balance:\t{alice.balance()}')
print(f'bob balance:\t{bob.balance()}')
alice_coin_id = alice_coin.name()
alice_coin_record = asyncio.run(
network.sim_client.get_coin_record_by_name(alice_coin_id))
print(alice_coin_record)
coin_spend: CoinSpend = asyncio.run(
network.sim_client.get_puzzle_and_solution(alice_coin_id, alice_coin_record.spent_block_index))
print(coin_spend.puzzle_reveal)
print(alice_puzzle)
print(coin_spend.solution)
assert alice_puzzle.get_tree_hash() == coin_spend.puzzle_reveal.get_tree_hash()
asyncio.run(network.close())