chore: move token example to nep5 as package name (CityOfZion/neo-storm#19)
* feat: add token example * feat: code splitted package * feat: use updated apis * chore: change token namespace to nep5 * chore: add transfer event and readme updates Imported from CityOfZion/neo-storm (63ec2d7dc23a60f128a8b383ceda1eaa15d919c1).
This commit is contained in:
parent
b3037cd598
commit
1f8ccdba16
4 changed files with 118 additions and 6 deletions
|
@ -1,7 +1,7 @@
|
|||
package token_contract
|
||||
|
||||
import (
|
||||
"token"
|
||||
"nep5"
|
||||
|
||||
"github.com/CityOfZion/neo-storm/interop/storage"
|
||||
"github.com/CityOfZion/neo-storm/interop/util"
|
||||
|
@ -15,8 +15,8 @@ const (
|
|||
var owner = util.FromAddress("AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y")
|
||||
|
||||
// CreateToken initializes the Token Interface for the Smart Contract to operate with
|
||||
func CreateToken() token.Token {
|
||||
return token.Token{
|
||||
func CreateToken() nep5.Token {
|
||||
return nep5.Token{
|
||||
Name: "Awesome NEO Token",
|
||||
Symbol: "ANT",
|
||||
Decimals: decimals,
|
||||
|
|
112
examples/token/vendor/nep5/nep5.go
vendored
Normal file
112
examples/token/vendor/nep5/nep5.go
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
package nep5
|
||||
|
||||
import (
|
||||
"github.com/CityOfZion/neo-storm/interop/engine"
|
||||
"github.com/CityOfZion/neo-storm/interop/runtime"
|
||||
"github.com/CityOfZion/neo-storm/interop/storage"
|
||||
)
|
||||
|
||||
// Token holds all token info
|
||||
type Token struct {
|
||||
// Token name
|
||||
Name string
|
||||
// Ticker symbol
|
||||
Symbol string
|
||||
// Amount of decimals
|
||||
Decimals int
|
||||
// Token owner address
|
||||
Owner []byte
|
||||
// Total tokens * multiplier
|
||||
TotalSupply int
|
||||
// Storage key for circulation value
|
||||
CirculationKey string
|
||||
}
|
||||
|
||||
// GetSupply gets the token totalSupply value from VM storage
|
||||
func (t Token) GetSupply(ctx storage.Context) interface{} {
|
||||
return storage.Get(ctx, t.CirculationKey)
|
||||
}
|
||||
|
||||
// BalanceOf gets the token balance of a specific address
|
||||
func (t Token) BalanceOf(ctx storage.Context, hodler []byte) interface{} {
|
||||
return storage.Get(ctx, hodler)
|
||||
}
|
||||
|
||||
// Transfer token from one user to another
|
||||
func (t Token) Transfer(ctx storage.Context, from []byte, to []byte, amount int) bool {
|
||||
amountFrom := t.CanTransfer(ctx, from, to, amount)
|
||||
if amountFrom == -1 {
|
||||
return false
|
||||
}
|
||||
|
||||
if amountFrom == 0 {
|
||||
storage.Delete(ctx, from)
|
||||
}
|
||||
|
||||
if amountFrom > 0 {
|
||||
diff := amountFrom - amount
|
||||
storage.Put(ctx, from, diff)
|
||||
}
|
||||
|
||||
amountTo := storage.Get(ctx, to).(int)
|
||||
totalAmountTo := amountTo + amount
|
||||
storage.Put(ctx, to, totalAmountTo)
|
||||
runtime.Notify("transfer", from, to, amount)
|
||||
return true
|
||||
}
|
||||
|
||||
// CanTransfer returns the amount it can transfer
|
||||
func (t Token) CanTransfer(ctx storage.Context, from []byte, to []byte, amount int) int {
|
||||
if len(to) != 20 && !IsUsableAddress(from) {
|
||||
return -1
|
||||
}
|
||||
|
||||
amountFrom := storage.Get(ctx, from).(int)
|
||||
if amountFrom < amount {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Tell Transfer the result is equal - special case since it uses Delete
|
||||
if amountFrom == amount {
|
||||
return 0
|
||||
}
|
||||
|
||||
// return amountFrom value back to Transfer, reduces extra Get
|
||||
return amountFrom
|
||||
}
|
||||
|
||||
// IsUsableAddress checks if the sender is either the correct NEO address or SC address
|
||||
func IsUsableAddress(addr []byte) bool {
|
||||
if len(addr) == 20 {
|
||||
|
||||
if runtime.CheckWitness(addr) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if a smart contract is calling scripthash
|
||||
callingScriptHash := engine.GetCallingScriptHash()
|
||||
if EqualAddresses(callingScriptHash, addr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// EqualAddresses compares two addresses if they're equal
|
||||
// also returns false if one of the two - or both - aren't actual addresses
|
||||
func EqualAddresses(a []byte, b []byte) bool {
|
||||
aLen := len(a)
|
||||
bLen := len(b)
|
||||
if aLen != bLen || aLen != 20 || bLen != 20 {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < aLen; i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
|
@ -12,7 +12,7 @@ func CheckWitness(hash []byte) bool {
|
|||
func Log(message string) {}
|
||||
|
||||
// Notify an event to the VM.
|
||||
func Notify(arg interface{}) int {
|
||||
func Notify(arg ...interface{}) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ func Serialize(item interface{}) []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Deserializes an item from a bytearray.
|
||||
// Deserialize an item from a bytearray.
|
||||
func Deserialize(b []byte) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func TestExamplesFolder(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
if len(infos) > 1 {
|
||||
t.Fatal("detected smart contract folder with more then 1 contract file")
|
||||
t.Fatal("detected smart contract folder with more than 1 contract file")
|
||||
}
|
||||
if len(infos) == 0 {
|
||||
t.Fatal("detected smart contract folder with no contract in it")
|
||||
|
|
Loading…
Reference in a new issue