-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathapplication.py
More file actions
145 lines (118 loc) · 4.17 KB
/
Copy pathapplication.py
File metadata and controls
145 lines (118 loc) · 4.17 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from typing import Literal
from pyteal import *
from beaker import *
# Define some types by name for handy reference
VrfProof = abi.StaticBytes[Literal[80]]
VrfHash = abi.StaticBytes[Literal[64]]
BlockSeed = abi.StaticBytes[Literal[32]]
class BlockDetails(abi.NamedTuple):
ts: abi.Field[abi.Uint64]
seed: abi.Field[BlockSeed]
Signature = abi.StaticBytes[Literal[64]]
class JsonExampleResult(abi.NamedTuple):
string_key: abi.Field[abi.String]
uint_key: abi.Field[abi.Uint64]
obj_key: abi.Field[abi.String]
class DemoAVM7(Application):
"""Examples for teal ops that are new for AVM 7"""
@external
def vrf_verify(
self,
msg: abi.DynamicBytes,
proof: VrfProof,
pub_key: abi.Address,
*,
output: VrfHash,
):
"""
Verify that some message was used to generate a proof generated by a given public key
Cost: Takes 5700 ops
"""
return Seq(
# Use the Algorand VRF
vrf_result := VrfVerify.algorand(
# Note: in practice the message is likely to be something like:
# sha512_256(concat(itob(round), block.seed(round)))
# Get the bytes from the message
msg.get(),
# Get the bytes from the proof
proof.get(),
# Note: in practice this is likely to be some hardcoded public key or one of
# a set of "pre-approved" public keys
# Get the pubkey bytes
pub_key.get(),
),
# Check Successful
Assert(vrf_result.output_slots[1].load() == Int(1)),
# Write the result to the output
output.set(vrf_result.output_slots[0].load()),
)
@external
def block(self, round: abi.Uint64, *, output: BlockDetails):
"""New block operations for getting timestamp or seed of a historical round"""
return Seq(
(ts := abi.Uint64()).set(Block.timestamp(round.get())),
(seed := abi.make(BlockSeed)).set(Block.seed(round.get())),
output.set(ts, seed),
)
@external
def b64decode(self, b64encoded: abi.String, *, output: abi.String):
"""Base64Decode can be used to decode either a std or url encoded string
Cost: 1 + 1 per 16 bytes of A
Note:
IF you have the option to decode prior to submitting the app call
transaction, you _should_.
This should _only_ be used in the case that there is no way to decode
the bytestring prior to submitting the transaction.
"""
return output.set(Base64Decode.std(b64encoded.get()))
@external
def json_ref(self, json_str: abi.String, *, output: JsonExampleResult):
"""
Cost: 25 + 2 per 7 bytes of A
"""
return Seq(
(s := abi.String()).set(
JsonRef.as_string(json_str.get(), Bytes("string_key"))
),
(i := abi.Uint64()).set(
JsonRef.as_uint64(json_str.get(), Bytes("uint_key"))
),
(o := abi.String()).set(
JsonRef.as_object(json_str.get(), Bytes("obj_key"))
),
output.set(s, i, o),
)
@external
def sha3_256(self, to_hash: abi.String, *, output: abi.DynamicBytes):
"""
Cost: 130
"""
return Seq(
output.set(Sha3_256(to_hash.get())),
)
@external
def replace(
self,
orig: abi.String,
start: abi.Uint64,
replace_with: abi.String,
*,
output: abi.String,
):
"""
replace(abcdef, 1, xyz) => axyzef
cannot _grow_ original string
"""
return output.set(Replace(orig.get(), start.get(), replace_with.get()))
@external
def ed25519verify_bare(
self, msg: abi.String, pubkey: abi.Address, sig: Signature, *, output: abi.Bool
):
return output.set(Ed25519Verify_Bare(msg.get(), sig.get(), pubkey.get()))
@external
def noop(self):
return Approve()
@delete(authorize=Authorize.only(Global.creator_address()))
def delete(self):
return Approve()