Skip to content

Commit

Permalink
Creator access and app_params_get (algorand#2301)
Browse files Browse the repository at this point in the history
Adds the ability to get the creator of apps and assets in teal.

This is a simple new field for `asset_params_get`, but it introduces a new opcode `app_params_get` to enable access for apps.  Meanwhile `app_params_get` allows access to other global parameters about an app - the schema sizes, extra pages, and the programs themselves.

This also begins work on LogicVersion=5, which should be AVM 1.0
  • Loading branch information
jannotti authored Jul 9, 2021
1 parent 6cfcbeb commit 398d606
Show file tree
Hide file tree
Showing 19 changed files with 655 additions and 254 deletions.
17 changes: 17 additions & 0 deletions cmd/opdoc/opdoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ func assetParamsFieldsMarkdown(out io.Writer) {
fieldTableMarkdown(out, logic.AssetParamsFieldNames, logic.AssetParamsFieldTypes, logic.AssetParamsFieldDocs)
}

func appParamsFieldsMarkdown(out io.Writer) {
fmt.Fprintf(out, "\n`app_params_get` Fields:\n\n")
fieldTableMarkdown(out, logic.AppParamsFieldNames, logic.AppParamsFieldTypes, logic.AppParamsFieldDocs)
}

func immediateMarkdown(op *logic.OpSpec) string {
markdown := ""
for _, imm := range op.Details.Immediates {
Expand Down Expand Up @@ -179,6 +184,8 @@ func opToMarkdown(out io.Writer, op *logic.OpSpec) (err error) {
assetHoldingFieldsMarkdown(out)
} else if op.Name == "asset_params_get" {
assetParamsFieldsMarkdown(out)
} else if op.Name == "app_params_get" {
appParamsFieldsMarkdown(out)
}
ode := logic.OpDocExtra(op.Name)
if ode != "" {
Expand Down Expand Up @@ -240,6 +247,9 @@ func argEnum(name string) []string {
if name == "asset_params_get" {
return logic.AssetParamsFieldNames
}
if name == "app_params_get" {
return logic.AppParamsFieldNames
}
return nil
}

Expand Down Expand Up @@ -281,6 +291,9 @@ func argEnumTypes(name string) string {
if name == "asset_params_get" {
return typeString(logic.AssetParamsFieldTypes)
}
if name == "app_params_get" {
return typeString(logic.AppParamsFieldTypes)
}

return ""
}
Expand Down Expand Up @@ -344,6 +357,10 @@ func main() {
fieldTableMarkdown(assetparams, logic.AssetParamsFieldNames, logic.AssetParamsFieldTypes, logic.AssetParamsFieldDocs)
assetparams.Close()

appparams, _ := os.Create("app_params_fields.md")
fieldTableMarkdown(appparams, logic.AppParamsFieldNames, logic.AppParamsFieldTypes, logic.AppParamsFieldDocs)
appparams.Close()

langspecjs, _ := os.Create("langspec.json")
enc := json.NewEncoder(langspecjs)
enc.Encode(buildLanguageSpec(opGroups))
Expand Down
5 changes: 4 additions & 1 deletion config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ func initConsensusProtocols() {
v28 := v27
v28.ApprovedUpgrades = map[protocol.ConsensusVersion]uint64{}

// Enable TEAL 4
// Enable TEAL 4 / AVM 0.9
v28.LogicSigVersion = 4
// Enable support for larger app program size
v28.MaxExtraAppProgramPages = 3
Expand Down Expand Up @@ -984,6 +984,9 @@ func initConsensusProtocols() {
vFuture.CompactCertWeightThreshold = (1 << 32) * 30 / 100
vFuture.CompactCertSecKQ = 128

// Enable TEAL 5 / AVM 1.0
vFuture.LogicSigVersion = 5

Consensus[protocol.ConsensusFuture] = vFuture
}

Expand Down
32 changes: 25 additions & 7 deletions data/transactions/logic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,17 @@ Some of these have immediate data in the byte or bytes after the opcode.
| 2 | FirstValid | uint64 | round number |
| 3 | FirstValidTime | uint64 | Causes program to fail; reserved for future use |
| 4 | LastValid | uint64 | round number |
| 5 | Note | []byte | |
| 6 | Lease | []byte | |
| 5 | Note | []byte | Any data up to 1024 bytes |
| 6 | Lease | []byte | 32 byte lease value |
| 7 | Receiver | []byte | 32 byte address |
| 8 | Amount | uint64 | micro-Algos |
| 9 | CloseRemainderTo | []byte | 32 byte address |
| 10 | VotePK | []byte | 32 byte address |
| 11 | SelectionPK | []byte | 32 byte address |
| 12 | VoteFirst | uint64 | |
| 13 | VoteLast | uint64 | |
| 14 | VoteKeyDilution | uint64 | |
| 15 | Type | []byte | |
| 12 | VoteFirst | uint64 | The first round that the participation key is valid. |
| 13 | VoteLast | uint64 | The last round that the participation key is valid. |
| 14 | VoteKeyDilution | uint64 | Dilution for the 2-level participation key |
| 15 | Type | []byte | Transaction type as bytes |
| 16 | TypeEnum | uint64 | See table below |
| 17 | XferAsset | uint64 | Asset ID |
| 18 | AssetAmount | uint64 | value in Asset's units |
Expand Down Expand Up @@ -309,7 +309,7 @@ Global fields are fields that are common to all the transactions in the group. I

**Asset Fields**

Asset fields include `AssetHolding` and `AssetParam` fields that are used in `asset_read_*` opcodes
Asset fields include `AssetHolding` and `AssetParam` fields that are used in the `asset_holding_get` and `asset_params_get` opcodes.

| Index | Name | Type | Notes |
| --- | --- | --- | --- |
Expand All @@ -330,6 +330,23 @@ Asset fields include `AssetHolding` and `AssetParam` fields that are used in `as
| 8 | AssetReserve | []byte | Reserve address |
| 9 | AssetFreeze | []byte | Freeze address |
| 10 | AssetClawback | []byte | Clawback address |
| 11 | AssetCreator | []byte | Creator address |


**App Fields**

App fields used in the `app_params_get` opcode.

| Index | Name | Type | Notes |
| --- | --- | --- | --- |
| 0 | AppApprovalProgram | []byte | Bytecode of Approval Program |
| 1 | AppClearStateProgram | []byte | Bytecode of Clear State Program |
| 2 | AppGlobalNumUint | uint64 | Number of uint64 values allowed in Global State |
| 3 | AppGlobalNumByteSlice | uint64 | Number of byte array values allowed in Global State |
| 4 | AppLocalNumUint | uint64 | Number of uint64 values allowed in Local State |
| 5 | AppLocalNumByteSlice | uint64 | Number of byte array values allowed in Local State |
| 6 | AppExtraProgramPages | uint64 | Number of Extra Program Pages of code space |
| 7 | AppCreator | []byte | Creator address |


### Flow Control
Expand Down Expand Up @@ -368,6 +385,7 @@ Asset fields include `AssetHolding` and `AssetParam` fields that are used in `as
| `app_global_del` | delete key A from a global state of the current application |
| `asset_holding_get i` | read from account A and asset B holding field X (imm arg) => {0 or 1 (top), value} |
| `asset_params_get i` | read from asset A params field X (imm arg) => {0 or 1 (top), value} |
| `app_params_get i` | read from app A params field X (imm arg) => {0 or 1 (top), value} |

# Assembler Syntax

Expand Down
8 changes: 7 additions & 1 deletion data/transactions/logic/README_in.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,18 @@ Global fields are fields that are common to all the transactions in the group. I

**Asset Fields**

Asset fields include `AssetHolding` and `AssetParam` fields that are used in `asset_read_*` opcodes
Asset fields include `AssetHolding` and `AssetParam` fields that are used in the `asset_holding_get` and `asset_params_get` opcodes.

@@ asset_holding_fields.md @@

@@ asset_params_fields.md @@

**App Fields**

App fields used in the `app_params_get` opcode.

@@ app_params_fields.md @@

### Flow Control

@@ Flow_Control.md @@
Expand Down
44 changes: 35 additions & 9 deletions data/transactions/logic/TEAL_opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Ops have a 'cost' of 1 unless otherwise specified.
- SHA256 hash of value X, yields [32]byte
- **Cost**:
- 7 (LogicSigVersion = 1)
- 35 (2 <= LogicSigVersion <= 4)
- 35 (2 <= LogicSigVersion <= 5)

## keccak256

Expand All @@ -28,7 +28,7 @@ Ops have a 'cost' of 1 unless otherwise specified.
- Keccak256 hash of value X, yields [32]byte
- **Cost**:
- 26 (LogicSigVersion = 1)
- 130 (2 <= LogicSigVersion <= 4)
- 130 (2 <= LogicSigVersion <= 5)

## sha512_256

Expand All @@ -38,7 +38,7 @@ Ops have a 'cost' of 1 unless otherwise specified.
- SHA512_256 hash of value X, yields [32]byte
- **Cost**:
- 9 (LogicSigVersion = 1)
- 45 (2 <= LogicSigVersion <= 4)
- 45 (2 <= LogicSigVersion <= 5)

## ed25519verify

Expand Down Expand Up @@ -374,17 +374,17 @@ Overflow is an error condition which halts execution and fails the transaction.
| 2 | FirstValid | uint64 | round number |
| 3 | FirstValidTime | uint64 | Causes program to fail; reserved for future use |
| 4 | LastValid | uint64 | round number |
| 5 | Note | []byte | |
| 6 | Lease | []byte | |
| 5 | Note | []byte | Any data up to 1024 bytes |
| 6 | Lease | []byte | 32 byte lease value |
| 7 | Receiver | []byte | 32 byte address |
| 8 | Amount | uint64 | micro-Algos |
| 9 | CloseRemainderTo | []byte | 32 byte address |
| 10 | VotePK | []byte | 32 byte address |
| 11 | SelectionPK | []byte | 32 byte address |
| 12 | VoteFirst | uint64 | |
| 13 | VoteLast | uint64 | |
| 14 | VoteKeyDilution | uint64 | |
| 15 | Type | []byte | |
| 12 | VoteFirst | uint64 | The first round that the participation key is valid. |
| 13 | VoteLast | uint64 | The last round that the participation key is valid. |
| 14 | VoteKeyDilution | uint64 | Dilution for the 2-level participation key |
| 15 | Type | []byte | Transaction type as bytes |
| 16 | TypeEnum | uint64 | See table below |
| 17 | XferAsset | uint64 | Asset ID |
| 18 | AssetAmount | uint64 | value in Asset's units |
Expand Down Expand Up @@ -877,10 +877,36 @@ params: Txn.Accounts offset (or, since v4, an account address that appears in Tx
| 8 | AssetReserve | []byte | Reserve address |
| 9 | AssetFreeze | []byte | Freeze address |
| 10 | AssetClawback | []byte | Clawback address |
| 11 | AssetCreator | []byte | Creator address |


params: Before v4, Txn.ForeignAssets offset. Since v4, Txn.ForeignAssets offset or an asset id that appears in Txn.ForeignAssets. Return: did_exist flag (1 if exist and 0 otherwise), value.

## app_params_get i

- Opcode: 0x72 {uint8 app params field index}
- Pops: *... stack*, uint64
- Pushes: *... stack*, any, uint64
- read from app A params field X (imm arg) => {0 or 1 (top), value}
- LogicSigVersion >= 5
- Mode: Application

`app_params_get` Fields:

| Index | Name | Type | Notes |
| --- | --- | --- | --- |
| 0 | AppApprovalProgram | []byte | Bytecode of Approval Program |
| 1 | AppClearStateProgram | []byte | Bytecode of Clear State Program |
| 2 | AppGlobalNumUint | uint64 | Number of uint64 values allowed in Global State |
| 3 | AppGlobalNumByteSlice | uint64 | Number of byte array values allowed in Global State |
| 4 | AppLocalNumUint | uint64 | Number of uint64 values allowed in Local State |
| 5 | AppLocalNumByteSlice | uint64 | Number of byte array values allowed in Local State |
| 6 | AppExtraProgramPages | uint64 | Number of Extra Program Pages of code space |
| 7 | AppCreator | []byte | Creator address |


params: Txn.ForeignApps offset or an app id that appears in Txn.ForeignApps. Return: did_exist flag (1 if exist and 0 otherwise), value.

## min_balance

- Opcode: 0x78
Expand Down
46 changes: 37 additions & 9 deletions data/transactions/logic/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,11 +980,11 @@ func assembleGtxnsa(ops *OpStream, spec *OpSpec, args []string) error {

func assembleGlobal(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.error("global expects one argument")
return ops.errorf("%s expects one argument", spec.Name)
}
fs, ok := globalFieldSpecByName[args[0]]
if !ok {
return ops.errorf("global unknown field: %#v", args[0])
return ops.errorf("%s unknown field: %#v", spec.Name, args[0])
}
if fs.version > ops.Version {
// no return here. we may as well continue to maintain typestack
Expand All @@ -1001,11 +1001,11 @@ func assembleGlobal(ops *OpStream, spec *OpSpec, args []string) error {

func assembleAssetHolding(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.error("asset_holding_get expects one argument")
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := assetHoldingFields[args[0]]
if !ok {
return ops.errorf("asset_holding_get unknown arg: %#v", args[0])
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
}
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
Expand All @@ -1015,18 +1015,32 @@ func assembleAssetHolding(ops *OpStream, spec *OpSpec, args []string) error {

func assembleAssetParams(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.error("asset_params_get expects one argument")
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := assetParamsFields[args[0]]
if !ok {
return ops.errorf("asset_params_get unknown arg: %#v", args[0])
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
}
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.returns(AssetParamsFieldTypes[val], StackUint64)
return nil
}

func assembleAppParams(ops *OpStream, spec *OpSpec, args []string) error {
if len(args) != 1 {
return ops.errorf("%s expects one argument", spec.Name)
}
val, ok := appParamsFields[args[0]]
if !ok {
return ops.errorf("%s unknown arg: %#v", spec.Name, args[0])
}
ops.pending.WriteByte(spec.Opcode)
ops.pending.WriteByte(uint8(val))
ops.returns(AppParamsFieldTypes[val], StackUint64)
return nil
}

type assembleFunc func(*OpStream, *OpSpec, []string) error

// Basic assembly. Any extra bytes of opcode are encoded as byte immediates.
Expand Down Expand Up @@ -2160,7 +2174,7 @@ func disGlobal(dis *disassembleState, spec *OpSpec) (string, error) {
if int(garg) >= len(GlobalFieldNames) {
return "", fmt.Errorf("invalid global arg index %d at pc=%d", garg, dis.pc)
}
return fmt.Sprintf("global %s", GlobalFieldNames[garg]), nil
return fmt.Sprintf("%s %s", spec.Name, GlobalFieldNames[garg]), nil
}

func disBranch(dis *disassembleState, spec *OpSpec) (string, error) {
Expand Down Expand Up @@ -2202,7 +2216,7 @@ func disAssetHolding(dis *disassembleState, spec *OpSpec) (string, error) {
if int(arg) >= len(AssetHoldingFieldNames) {
return "", fmt.Errorf("invalid asset holding arg index %d at pc=%d", arg, dis.pc)
}
return fmt.Sprintf("asset_holding_get %s", AssetHoldingFieldNames[arg]), nil
return fmt.Sprintf("%s %s", spec.Name, AssetHoldingFieldNames[arg]), nil
}

func disAssetParams(dis *disassembleState, spec *OpSpec) (string, error) {
Expand All @@ -2216,7 +2230,21 @@ func disAssetParams(dis *disassembleState, spec *OpSpec) (string, error) {
if int(arg) >= len(AssetParamsFieldNames) {
return "", fmt.Errorf("invalid asset params arg index %d at pc=%d", arg, dis.pc)
}
return fmt.Sprintf("asset_params_get %s", AssetParamsFieldNames[arg]), nil
return fmt.Sprintf("%s %s", spec.Name, AssetParamsFieldNames[arg]), nil
}

func disAppParams(dis *disassembleState, spec *OpSpec) (string, error) {
lastIdx := dis.pc + 1
if len(dis.program) <= lastIdx {
missing := lastIdx - len(dis.program) + 1
return "", fmt.Errorf("unexpected %s opcode end: missing %d bytes", spec.Name, missing)
}
dis.nextpc = dis.pc + 2
arg := dis.program[dis.pc+1]
if int(arg) >= len(AppParamsFieldNames) {
return "", fmt.Errorf("invalid app params arg index %d at pc=%d", arg, dis.pc)
}
return fmt.Sprintf("%s %s", spec.Name, AppParamsFieldNames[arg]), nil
}

type disInfo struct {
Expand Down
9 changes: 8 additions & 1 deletion data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,20 +289,27 @@ gload 0 0
gloads 0
gaid 0
gaids
int 100
`

const v5Nonsense = `
app_params_get AppExtraProgramPages
`

var nonsense = map[uint64]string{
1: v1Nonsense,
2: v1Nonsense + v2Nonsense,
3: v1Nonsense + v2Nonsense + v3Nonsense,
4: v1Nonsense + v2Nonsense + v3Nonsense + v4Nonsense,
5: v1Nonsense + v2Nonsense + v3Nonsense + v4Nonsense + v5Nonsense,
}

var compiled = map[uint64]string{
1: "012008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b1716154000032903494",
2: "022008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f",
3: "032008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f4478222105531421055427042106552105082106564c4d4b02210538212106391c0081e80780046a6f686e",
4: "042004010200b7a60c26040242420c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482a50512a632223524100034200004322602261222b634848222862482864286548482228236628226724286828692422700048482471004848361c0037001a0031183119311b311d311e311f312024221e312131223123312431253126312731283129312a312b312c312d312e312f44782522531422542b2355220823564c4d4b0222382123391c0081e80780046a6f686e2281d00f24231f880003420001892223902291922394239593a0a1a2a3a4a5a6a7a8a9aaabacadae23af3a00003b003c003d",
4: "042004010200b7a60c26040242420c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482a50512a632223524100034200004322602261222b634848222862482864286548482228236628226724286828692422700048482471004848361c0037001a0031183119311b311d311e311f312024221e312131223123312431253126312731283129312a312b312c312d312e312f44782522531422542b2355220823564c4d4b0222382123391c0081e80780046a6f686e2281d00f24231f880003420001892223902291922394239593a0a1a2a3a4a5a6a7a8a9aaabacadae23af3a00003b003c003d8164",
5: "052004010200b7a60c26040242420c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482a50512a632223524100034200004322602261222b634848222862482864286548482228236628226724286828692422700048482471004848361c0037001a0031183119311b311d311e311f312024221e312131223123312431253126312731283129312a312b312c312d312e312f44782522531422542b2355220823564c4d4b0222382123391c0081e80780046a6f686e2281d00f24231f880003420001892223902291922394239593a0a1a2a3a4a5a6a7a8a9aaabacadae23af3a00003b003c003d81647206",
}

func pseudoOp(opcode string) bool {
Expand Down
Loading

0 comments on commit 398d606

Please sign in to comment.