Skip to content

Commit

Permalink
Merge branch 'release/v1.10.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
algobarb committed Aug 3, 2021
2 parents 2afc9ee + 6994fe9 commit 3f3465b
Show file tree
Hide file tree
Showing 16 changed files with 1,169 additions and 64 deletions.
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: "\U0001F41C Bug report"
about: Report a reproducible bug.
title: ''
labels: new-bug
assignees: ''

---

### Subject of the issue

<!-- Describe your issue here. -->

### Your environment

<!--
* Software version: `algod -v`
* Node status if applicable: `goal node status`
* Operating System details.
* In many cases log files and cadaver files are also useful to include. Since these files may be large, an Algorand developer may request them later. These files may include public addresses that you're participating with. If that is a concern please be sure to scrub that data.
-->

### Steps to reproduce

1.
2.

### Expected behaviour

### Actual behaviour
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: "\U0001F514 Feature Request"
about: Suggestions for how we can improve the algorand platform.
title: ''
labels: new-feature-request
assignees: ''
---

## Problem

<!-- What is the problem that we’re trying to solve? -->

## Solution

<!-- Do you have a potential/suggested solution? Document more than one if possible. -->

## Dependencies

<!-- Does the solution have any team or design dependencies? -->

## Urgency

<!-- What is the urgency here and why? -->
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ go:
- "1.12"
- "1.13"
- "1.14"
- "1.15"
- "1.16"
install:
- go get -u golang.org/x/lint/golint
script:
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 1.10.0
# Added
- New github Issue template
- Signing support for rekeying to LogicSig/MultiSig account
- Asset Base64 Fields
# BugFix
- Use correct go version in CI
# BugFix
# 1.9.2
# Bug Fix
- Update FromBase64String() to correctly return the signed transaction
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ TEST_SOURCES_NO_CUCUMBER := $(shell cd $(SRCPATH) && go list ./... | grep -v tes
lint:
golint `go list ./... | grep -v /vendor/`

fmt:
go fmt ./...

generate:
cd $(SRCPATH) && go generate ./logic

build: generate
cd $(SRCPATH) && go test -run xxx_phony_test $(TEST_SOURCES)

test:
go test $(TEST_SOURCES_NO_CUCUMBER)

unit:
go test $(TEST_SOURCES_NO_CUCUMBER)
cd test && go test --godog.strict=true --godog.format=pretty --godog.tags="@unit.offline,@unit.algod,@unit.indexer,@unit.rekey,@unit.tealsign,@unit.dryrun,@unit.responses,@unit.applications,@unit.transactions,@unit.indexer.rekey,@unit.responses.messagepack,@unit.responses.231,@unit.responses.messagepack.231,@unit.responses.genesis,@unit.feetest" --test.v .
Expand All @@ -21,3 +27,5 @@ integration:

docker-test:
./test/docker/run_docker.sh

.PHONY: test fmt
21 changes: 18 additions & 3 deletions client/v2/common/models/asset_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,33 @@ type AssetParams struct {
// this metadata is up to the application.
MetadataHash []byte `json:"metadata-hash,omitempty"`

// Name (an) Name of this asset, as supplied by the creator.
// Name (an) Name of this asset, as supplied by the creator. Included only when the
// asset name is composed of printable utf-8 characters.
Name string `json:"name,omitempty"`

// NameB64 base64 encoded name of this asset, as supplied by the creator.
NameB64 []byte `json:"name-b64,omitempty"`

// Reserve (r) Address of account holding reserve (non-minted) units of this asset.
Reserve string `json:"reserve,omitempty"`

// Total (t) The total number of units of this asset.
Total uint64 `json:"total"`

// UnitName (un) Name of a unit of this asset, as supplied by the creator.
// UnitName (un) Name of a unit of this asset, as supplied by the creator. Included
// only when the name of a unit of this asset is composed of printable utf-8
// characters.
UnitName string `json:"unit-name,omitempty"`

// Url (au) URL where more information about the asset can be retrieved.
// UnitNameB64 base64 encoded name of a unit of this asset, as supplied by the
// creator.
UnitNameB64 []byte `json:"unit-name-b64,omitempty"`

// Url (au) URL where more information about the asset can be retrieved. Included
// only when the URL is composed of printable utf-8 characters.
Url string `json:"url,omitempty"`

// UrlB64 base64 encoded URL where more information about the asset can be
// retrieved.
UrlB64 []byte `json:"url-b64,omitempty"`
}
207 changes: 206 additions & 1 deletion crypto/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package crypto

import (
"crypto/sha512"
"errors"
"fmt"

"golang.org/x/crypto/ed25519"
Expand Down Expand Up @@ -50,6 +51,30 @@ func GenerateAccount() (kp Account) {
return
}

// AccountFromPrivateKey derives the remaining Account fields from only a
// private key. The argument sk must have a length equal to
// ed25519.PrivateKeySize.
func AccountFromPrivateKey(sk ed25519.PrivateKey) (account Account, err error) {
if len(sk) != ed25519.PrivateKeySize {
err = errInvalidPrivateKey
return
}

// copy sk
account.PrivateKey = make(ed25519.PrivateKey, len(sk))
copy(account.PrivateKey, sk)

account.PublicKey = sk.Public().(ed25519.PublicKey)
if len(account.PublicKey) != ed25519.PublicKeySize {
err = errors.New("generated public key is the wrong size")
return
}

copy(account.Address[:], account.PublicKey)

return
}

/* Multisig Support */

// MultisigAccount is a convenience type for holding multisig preimage data
Expand Down Expand Up @@ -133,7 +158,12 @@ func (ma MultisigAccount) Blank() bool {
return true
}

// LogicSigAddress returns contract (escrow) address
/* LogicSig support */

// LogicSigAddress returns the contract (escrow) address for a LogicSig.
//
// NOTE: If the LogicSig is delegated to another account this will not
// return the delegated address of the LogicSig.
func LogicSigAddress(lsig types.LogicSig) types.Address {
toBeSigned := programToSign(lsig.Logic)
checksum := sha512.Sum512_256(toBeSigned)
Expand All @@ -145,3 +175,178 @@ func LogicSigAddress(lsig types.LogicSig) types.Address {
}
return addr
}

// LogicSigAccount represents an account that can sign with a LogicSig program.
type LogicSigAccount struct {
_struct struct{} `codec:",omitempty,omitemptyarray"`

// The underlying LogicSig object
Lsig types.LogicSig `codec:"lsig"`

// The key that provided Lsig.Sig, if any
SigningKey ed25519.PublicKey `codec:"sigkey"`
}

// MakeLogicSigAccountEscrow creates a new escrow LogicSigAccount. The address
// of this account will be a hash of its program.
func MakeLogicSigAccountEscrow(program []byte, args [][]byte) LogicSigAccount {
return LogicSigAccount{
Lsig: types.LogicSig{
Logic: program,
Args: args,
},
}
}

// MakeLogicSigAccountDelegated creates a new delegated LogicSigAccount. This
// type of LogicSig has the authority to sign transactions on behalf of another
// account, called the delegating account. If the delegating account is a
// multisig account, use MakeLogicSigAccountDelegated instead.
//
// The parameter signer is the private key of the delegating account.
func MakeLogicSigAccountDelegated(program []byte, args [][]byte, signer ed25519.PrivateKey) (lsa LogicSigAccount, err error) {
var ma MultisigAccount
lsig, err := MakeLogicSig(program, args, signer, ma)
if err != nil {
return
}

signerAccount, err := AccountFromPrivateKey(signer)
if err != nil {
return
}

lsa = LogicSigAccount{
Lsig: lsig,
// attach SigningKey to remember which account the signature belongs to
SigningKey: signerAccount.PublicKey,
}
return
}

// MakeLogicSigAccountDelegatedMsig creates a new delegated LogicSigAccount.
// This type of LogicSig has the authority to sign transactions on behalf of
// another account, called the delegating account. Use this function if the
// delegating account is a multisig account, otherwise use
// MakeLogicSigAccountDelegated.
//
// The parameter msigAccount is the delegating multisig account.
//
// The parameter signer is the private key of one of the members of the
// delegating multisig account. Use the method AppendMultisigSignature on the
// returned LogicSigAccount to add additional signatures from other members.
func MakeLogicSigAccountDelegatedMsig(program []byte, args [][]byte, msigAccount MultisigAccount, signer ed25519.PrivateKey) (lsa LogicSigAccount, err error) {
lsig, err := MakeLogicSig(program, args, signer, msigAccount)
if err != nil {
return
}
lsa = LogicSigAccount{
Lsig: lsig,
// do not attach SigningKey, since that doesn't apply to an msig signature
}
return
}

// AppendMultisigSignature adds an additional signature from a member of the
// delegating multisig account.
//
// The LogicSigAccount must represent a delegated LogicSig backed by a multisig
// account.
func (lsa *LogicSigAccount) AppendMultisigSignature(signer ed25519.PrivateKey) error {
return AppendMultisigToLogicSig(&lsa.Lsig, signer)
}

// LogicSigAccountFromLogicSig creates a LogicSigAccount from an existing
// LogicSig object.
//
// The parameter signerPublicKey must be present if the LogicSig is delegated
// and the delegating account is backed by a single private key (i.e. not a
// multisig account). In this case, signerPublicKey must be the public key of
// the delegating account. In all other cases, an error will be returned if
// signerPublicKey is present.
func LogicSigAccountFromLogicSig(lsig types.LogicSig, signerPublicKey *ed25519.PublicKey) (lsa LogicSigAccount, err error) {
hasSig := lsig.Sig != (types.Signature{})
hasMsig := !lsig.Msig.Blank()

if hasSig && hasMsig {
err = errLsigTooManySignatures
return
}

if hasSig {
if signerPublicKey == nil {
err = errLsigNoPublicKey
return
}

toBeSigned := programToSign(lsig.Logic)
valid := ed25519.Verify(*signerPublicKey, toBeSigned, lsig.Sig[:])
if !valid {
err = errLsigInvalidPublicKey
return
}

lsa.Lsig = lsig
lsa.SigningKey = make(ed25519.PublicKey, len(*signerPublicKey))
copy(lsa.SigningKey, *signerPublicKey)
return
}

if signerPublicKey != nil {
err = errLsigAccountPublicKeyNotNeeded
return
}

lsa.Lsig = lsig
return
}

// IsDelegated returns true if and only if the LogicSig has been delegated to
// another account with a signature.
//
// Note this function only checks for the presence of a delegation signature. To
// verify the delegation signature, use VerifyLogicSig.
func (lsa LogicSigAccount) IsDelegated() bool {
hasSig := lsa.Lsig.Sig != (types.Signature{})
hasMsig := !lsa.Lsig.Msig.Blank()
return hasSig || hasMsig
}

// Address returns the address of this LogicSigAccount.
//
// If the LogicSig is delegated to another account, this will return the address
// of that account.
//
// If the LogicSig is not delegated to another account, this will return an
// escrow address that is the hash of the LogicSig's program code.
func (lsa LogicSigAccount) Address() (addr types.Address, err error) {
hasSig := lsa.Lsig.Sig != (types.Signature{})
hasMsig := !lsa.Lsig.Msig.Blank()

// require at most one sig
if hasSig && hasMsig {
err = errLsigTooManySignatures
return
}

if hasSig {
n := copy(addr[:], lsa.SigningKey)
if n != ed25519.PublicKeySize {
err = fmt.Errorf("Generated public key has length of %d, expected %d", n, ed25519.PublicKeySize)
}
return
}

if hasMsig {
var msigAccount MultisigAccount
msigAccount, err = MultisigAccountFromSig(lsa.Lsig.Msig)
if err != nil {
return
}
addr, err = msigAccount.Address()
return
}

addr = LogicSigAddress(lsa.Lsig)
return
}
Loading

0 comments on commit 3f3465b

Please sign in to comment.