Skip to content
This repository has been archived by the owner on Jan 25, 2021. It is now read-only.

Commit

Permalink
several things...
Browse files Browse the repository at this point in the history
  • Loading branch information
apisit committed Oct 17, 2018
1 parent 2c12bf1 commit 414172c
Show file tree
Hide file tree
Showing 25 changed files with 1,088 additions and 80 deletions.
64 changes: 64 additions & 0 deletions neoutils/deploy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package neoutils_test

import (
"bytes"
"log"
"testing"

"github.com/o3labs/neo-utils/neoutils"
"github.com/o3labs/neo-utils/neoutils/smartcontract"
)

func TestDeploy(t *testing.T) {

contract := neoutils.SmartContractInfo{
AVMHEX: "54c56b6c766b00527ac46c766b51527ac46168164e656f2e52756e74696d652e47657454726967676572635e0061149ba59c6b61d40aecf939c72cf1b6d21bba346dc2c00114907c907c9e63380061149ba59c6b61d40aecf939c72cf1b6d21bba346dc26168184e656f2e52756e74696d652e436865636b5769746e657373616c756600616c75666168164e656f2e52756e74696d652e4765745472696767657260907c907c9e630b016c766b00c3066465706c6f7987640b0061652501616c75666c766b00c30b746f74616c537570706c7987640b0061655b02616c75666c766b00c3046e616d6587640b006165c900616c75666c766b00c30673796d626f6c87640b006165c700616c75666c766b00c3087472616e7366657287644a006c766b51c3c0539c63080000616c75666c766b51c300c36c766b51c351c36c766b52527ac46c766b51c352c36c766b53527ac46c766b52c36c766b53c3615272651302616c75666c766b00c30962616c616e63654f66876422006c766b51c3c0519c63080000616c75666c766b51c300c36165d103616c75666c766b00c308646563696d616c7387640b0061652d00616c756600616c756600c56b0e5374656d2043656c6c20436f696e616c756600c56b03534343616c756600c56b58616c756600c56b6114f106089975d5964c41b5c80136814257665312326168184e656f2e52756e74696d652e436865636b5769746e65737363080000616c75666168164e656f2e53746f726167652e476574436f6e746578740b746f74616c537570706c79617c680f4e656f2e53746f726167652e476574c064080000616c75666168164e656f2e53746f726167652e476574436f6e7465787461149ba59c6b61d40aecf939c72cf1b6d21bba346dc2080000b2d3595bf006615272680f4e656f2e53746f726167652e5075746168164e656f2e53746f726167652e476574436f6e746578740b746f74616c537570706c79080000b2d3595bf006615272680f4e656f2e53746f726167652e507574610061149ba59c6b61d40aecf939c72cf1b6d21bba346dc2080000b2d3595bf006615272087472616e7366657254c168124e656f2e52756e74696d652e4e6f7469667951616c756600c56b6168164e656f2e53746f726167652e476574436f6e746578740b746f74616c537570706c79617c680f4e656f2e53746f726167652e476574616c756655c56b6c766b00527ac46c766b51527ac46c766b52527ac46c766b52c300a164080000616c75666c766b00c36168184e656f2e52756e74696d652e436865636b5769746e65737363080000616c75666c766b51c3c001149c63080000616c75666168164e656f2e53746f726167652e476574436f6e746578746c766b00c3617c680f4e656f2e53746f726167652e4765746c766b53527ac46c766b53c36c766b52c39f64080000616c75666c766b00c36c766b51c3907c907c9e63080051616c75666c766b53c36c766b52c39c643a006168164e656f2e53746f726167652e476574436f6e746578746c766b00c3617c68124e656f2e53746f726167652e44656c6574656240006168164e656f2e53746f726167652e476574436f6e746578746c766b00c36c766b53c36c766b52c394615272680f4e656f2e53746f726167652e5075746168164e656f2e53746f726167652e476574436f6e746578746c766b51c3617c680f4e656f2e53746f726167652e4765746c766b54527ac46168164e656f2e53746f726167652e476574436f6e746578746c766b51c36c766b54c36c766b52c393615272680f4e656f2e53746f726167652e507574616c766b00c36c766b51c36c766b52c3615272087472616e7366657254c168124e656f2e52756e74696d652e4e6f7469667951616c756651c56b6c766b00527ac46168164e656f2e53746f726167652e476574436f6e746578746c766b00c3617c680f4e656f2e53746f726167652e476574616c7566",
Name: "Stem Cell Coin",
Version: "1.0",
Author: "MTA Intec PTE LTD",
Email: "[email protected]",
Description: "SCC Token - https://www.stemcell-pj.net/",
InputTypes: []smartcontract.ParameterType{smartcontract.String, smartcontract.Array},
ReturnType: smartcontract.ByteArray,
Properties: smartcontract.HasStorage + smartcontract.Payable,
}

log.Printf("sc hash %v", contract.GetScriptHash())

asset := smartcontract.GAS
amount := float64(490)

encryptedKey := ""
passphrase := ""
wif, _ := neoutils.NEP2Decrypt(encryptedKey, passphrase)

privateNetwallet, err := neoutils.GenerateFromWIF(wif)
if err != nil {
log.Printf("%v", err)
t.Fail()
return
}
log.Printf("wallet address %v", privateNetwallet.Address)

unspent, err := utxo("main", privateNetwallet.Address)
log.Printf("unspent %+v", unspent)
if err != nil {
log.Printf("error %v", err)
t.Fail()
return
}
attributes := map[smartcontract.TransactionAttribute][]byte{}
tx, err := neoutils.DeploySmartContractScript(contract, *privateNetwallet, asset, amount, unspent, attributes)
if err != nil {
log.Printf("error %v", err)
return
}
log.Printf("tx %x", tx)

}

func TestVarInt(t *testing.T) {
buff := new(bytes.Buffer)
neoutils.WriteVarUint(buff, uint64(286))
log.Printf("%x", buff.Bytes())
}
135 changes: 135 additions & 0 deletions neoutils/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package neoutils

import (
"bytes"
"encoding/binary"
"io"
"log"

"github.com/o3labs/neo-utils/neoutils/smartcontract"
)

func WriteVarUint(w io.Writer, val uint64) error {
if val < 0xfd {
binary.Write(w, binary.LittleEndian, uint8(val))
return nil
}
if val < 0xFFFF {
binary.Write(w, binary.LittleEndian, byte(0xfd))
binary.Write(w, binary.LittleEndian, uint16(val))
return nil
}
if val < 0xFFFFFFFF {
binary.Write(w, binary.LittleEndian, byte(0xfe))
binary.Write(w, binary.LittleEndian, uint32(val))
return nil
}

binary.Write(w, binary.LittleEndian, byte(0xff))
binary.Write(w, binary.LittleEndian, val)

return nil
}

type SmartContractInfo struct {
AVMHEX string
Name string
Version string
Author string
Email string
Description string
Properties smartcontract.Properties
InputTypes []smartcontract.ParameterType
ReturnType smartcontract.ParameterType
}

func (s *SmartContractInfo) GetScriptHash() string {
address := VMCodeToNEOAddress(hex2bytes(s.AVMHEX))
scripthash := NEOAddressToScriptHashWithEndian(address, binary.BigEndian)
return scripthash
}

func (s *SmartContractInfo) Serialize() []byte {

params := []byte{}
for _, p := range s.InputTypes {
params = append(params, p.Byte())
}

scriptBuilder := smartcontract.NewScriptBuilder()
scriptBuilder.Push([]byte(s.Description))
scriptBuilder.Push([]byte(s.Email))
scriptBuilder.Push([]byte(s.Author))
scriptBuilder.Push([]byte(s.Version))
scriptBuilder.Push([]byte(s.Name))
scriptBuilder.Push(int(s.Properties))
scriptBuilder.Push([]byte{s.ReturnType.Byte()})
scriptBuilder.Push(params)
scriptBuilder.PushVarData(hex2bytes(s.AVMHEX))
scriptBuilder.PushSysCall("Neo.Contract.Create")

b := scriptBuilder.ToBytes()
buff := new(bytes.Buffer)
WriteVarUint(buff, uint64(len(b)))
endPayload := []byte{}
endPayload = append(endPayload, buff.Bytes()...)
endPayload = append(endPayload, b...)
return endPayload
}

func DeploySmartContractScript(contractInfo SmartContractInfo, wallet Wallet, asset smartcontract.NativeAsset, amount float64, unspent smartcontract.Unspent, attributes map[smartcontract.TransactionAttribute][]byte) ([]byte, error) {

tx := smartcontract.NewInvocationTransactionPayable()

tx.Data = contractInfo.Serialize()
tx.GAS = uint64(490)

amountToSend := amount
assetToSend := asset

networkFee := smartcontract.NetworkFeeAmount(0)

txInputs, err := smartcontract.NewScriptBuilder().GenerateTransactionInput(unspent, assetToSend, amountToSend, networkFee)
if err != nil {
return nil, err
}
tx.Inputs = txInputs

txAttributes, err := smartcontract.NewScriptBuilder().GenerateTransactionAttributes(attributes)
if err != nil {
return nil, err
}
tx.Attributes = txAttributes

//when deploy smart contract, you don't actually send asset to another address
//so the receiver is the same address
sender := smartcontract.ParseNEOAddress(wallet.Address)
receiver := smartcontract.ParseNEOAddress(wallet.Address)
txOutputs, err := smartcontract.NewScriptBuilder().GenerateTransactionOutputPayableGAS(sender, receiver, unspent, assetToSend, amount, networkFee, float64(tx.GAS))
if err != nil {
return nil, err
}

tx.Outputs = txOutputs

//begin signing process and invocation script
privateKeyInHex := bytesToHex(wallet.PrivateKey)
signedData, err := Sign(tx.ToBytes(), privateKeyInHex)
if err != nil {
return nil, err
}

signature := smartcontract.TransactionSignature{
SignedData: signedData,
PublicKey: wallet.PublicKey,
}

scripts := []interface{}{signature}
txScripts := smartcontract.NewScriptBuilder().GenerateVerificationScripts(scripts)
tx.Script = txScripts
//end signing process

log.Printf("txid = %v", tx.ToTXID())

return tx.ToBytes(), nil
}
22 changes: 22 additions & 0 deletions neoutils/mobile.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package neoutils

import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"log"
"strconv"
"strings"

Expand Down Expand Up @@ -122,3 +125,22 @@ func GenerateNEP6FromEncryptedKey(walletName, addressLabel, address, encryptedKe
}
return string(b)
}

func SerializeTX(jsonString string) []byte {
tx := NeonJSTransaction{}
json.Unmarshal([]byte(jsonString), &tx)
log.Printf("%+v", tx)
final := NeonJSTXSerializer(tx)
return final
}

func NEOAddresstoScriptHashBigEndian(neoAddress string) string {
return NEOAddressToScriptHashWithEndian(neoAddress, binary.BigEndian)
}

func GetVarUInt(value int64) []byte {
buff := new(bytes.Buffer)
WriteVarUint(buff, uint64(value))

return buff.Bytes()
}
66 changes: 57 additions & 9 deletions neoutils/mobile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,27 @@ import (
)

func TestMintTokensFromMobile(t *testing.T) {
scriptHash := "0x3e390ae61acb6713389c8fbbd47d1d69c32655a3"
scriptHash := "9121e89e8a0849857262d67c8408601b5e8e0524"

// encryptedKey := ""
// passphrase := ""
// wif, _ := neoutils.NEP2Decrypt(encryptedKey, passphrase)
wif := ""
wallet, _ := neoutils.GenerateFromWIF(wif)
log.Printf("address = %v\n address hash = %x", wallet.Address, wallet.HashedSignature)
wallet, err := neoutils.GenerateFromWIF(wif)
if err != nil {
log.Printf("%v", err)
t.Fail()
return
}

neo := string(smartcontract.NEO)
// gas := string(smartcontract.GAS)
amount := float64(2)
remark := "O3XMOONLIGHT2"
network := "test"
log.Printf("address = %v\n address hash = %x", wallet.Address, wallet.HashedSignature)
// neo := string(smartcontract.NEO)
gas := string(smartcontract.GAS)
amount := float64(1)
remark := "FIRST! APISIT FROM O3 :D"
network := "main"
networkFeeAmountInGAS := float64(0)
tx, err := neoutils.MintTokensRawTransactionMobile(network, scriptHash, wif, neo, amount, remark, networkFeeAmountInGAS)
tx, err := neoutils.MintTokensRawTransactionMobile(network, scriptHash, wif, gas, amount, remark, networkFeeAmountInGAS)
if err != nil {
log.Printf("%v", err)
t.Fail()
Expand All @@ -48,3 +56,43 @@ func TestNEP6MobileMethod(t *testing.T) {
log.Printf("%+v", nep6Wallet)

}

func TestSerializeTX(t *testing.T) {
data := `
{
"sha256": "ab1ad3efa1bf2fca51219b73c676dadaf9f446b81acd72f2557fecb7a8e7d243",
"type": 209,
"attributes": [{
"usage": 32,
"data": "4d17abe11020df91ce627af28c03c9c0cfb2a6c4"
}],
"scripts": [],
"gas": 0,
"version": 1,
"hash": "a67d3f9314383c4f7234cc9c8b7cf50602f91bf908bf6496a0c81bdc37fac7da",
"inputs": [{
"prevIndex": 0,
"prevHash": "d21043bb53d70a4762ebad4fcd55fb00528f4898d97cbe4182aef5b91139ec60"
}, {
"prevIndex": 6,
"prevHash": "6005967b1f6697d03cf241995fd4b2e71e56945ce0e4f815033700b993150c15"
}],
"outputs": [{
"assetId": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7",
"scriptHash": "e707714512577b42f9a011f8b870625429f93573",
"value": 1e-08
}],
"script": "0800e1f505000000001432e125258b7db0a0dffde5bd03b2b859253538ab144d17abe11020df91ce627af28c03c9c0cfb2a6c453c1076465706f73697467823b63e7c70a795a7615a38d1ba67d9e54c195a1"
}
`
final := neoutils.SerializeTX(data)
log.Printf("%x", final)
}

func TestNEOAddresstoScriptHashBigEndian(t *testing.T) {
log.Printf("%v", neoutils.NEOAddresstoScriptHashBigEndian("AQV8FNNi2o7EtMNn4etWBYx1cqBREAifgE"))
}

func TestGetVarUInt(t *testing.T) {
log.Printf("%x", neoutils.GetVarUInt(286))
}
18 changes: 11 additions & 7 deletions neoutils/multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,29 @@ import (
)

type MultiSigInterface interface {
CreateMultiSigRedeemScript(numerOfRequiredSignature int, publicKeys [][]byte) ([]byte, error)
CreateMultiSigRedeemScript() ([]byte, error)
}

type MultiSig struct{}
type MultiSig struct {
NumberOfRequiredSignatures int
PublicKeys [][]byte
}

var _ MultiSigInterface = (*MultiSig)(nil)

func (m *MultiSig) CreateMultiSigRedeemScript(numerOfRequiredSignature int, publicKeys [][]byte) ([]byte, error) {
numberOfPublicKeys := len(publicKeys)
func (m *MultiSig) CreateMultiSigRedeemScript() ([]byte, error) {

numberOfPublicKeys := len(m.PublicKeys)
if numberOfPublicKeys <= 1 {
return nil, fmt.Errorf("Number of required Signature must be more than one")
}
if numerOfRequiredSignature > numberOfPublicKeys {
if m.NumberOfRequiredSignatures > numberOfPublicKeys {
return nil, fmt.Errorf("Number of required Signature is more than public keys provided.")
}

//sort public key
keys := []btckey.PublicKey{}
for _, pb := range publicKeys {
for _, pb := range m.PublicKeys {
publicKey := btckey.PublicKey{}
publicKey.FromBytes(pb)
keys = append(keys, publicKey)
Expand All @@ -38,7 +42,7 @@ func (m *MultiSig) CreateMultiSigRedeemScript(numerOfRequiredSignature int, publ
sort.SliceStable(keys, func(i, j int) bool { return keys[i].Point.X.Cmp(keys[j].Point.X) == -1 })

sb := smartcontract.NewScriptBuilder()
sb.Push(numerOfRequiredSignature)
sb.Push(m.NumberOfRequiredSignatures)
for _, publicKey := range keys {
sb.Push(publicKey.ToBytes())
}
Expand Down
15 changes: 9 additions & 6 deletions neoutils/multisig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ import (
)

func TestGenerateMultiSigAddress(t *testing.T) {

pb1 := "02e77ff280db51ef3638009f11947c544ed094d4e5f2d96a9e654dc817bc3a8986"
pb2 := "024da93f9a66981e499b36ce763e57fd89a47a052e86d40b42f81708c40fe9eff0"
require := 2
// 1/2
pb1 := "024e543aee592c4dd2361f8e02b4275e18eb665bcfb1c4b6c09bc6aed125b2f13c"
pb2 := "030adab68b3eeb02734f65b8ced64f023e70c15bcdfae94c3e74b9d647ddf9c976"
require := 1
pubKeys := [][]byte{}

pubKeys = append(pubKeys, neoutils.HexTobytes(pb1))
pubKeys = append(pubKeys, neoutils.HexTobytes(pb2))

multisign := neoutils.MultiSig{}
vmCode, err := multisign.CreateMultiSigRedeemScript(require, pubKeys)
multisign := neoutils.MultiSig{
NumberOfRequiredSignatures: require,
PublicKeys: pubKeys,
}
vmCode, err := multisign.CreateMultiSigRedeemScript()
if err != nil {
log.Printf("%v", err)
}
Expand Down
4 changes: 0 additions & 4 deletions neoutils/native_asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ func (n *NativeAsset) SendNativeAssetRawTransaction(wallet Wallet, asset smartco
SignedData: signedData,
PublicKey: wallet.PublicKey,
}
// try to verify it
// hash := sha256.Sum256(tx.ToBytes())
// valid := Verify(wallet.PublicKey, signedData, hash[:])
// log.Printf("verify tx %v", valid)

scripts := []interface{}{signature}
txScripts := smartcontract.NewScriptBuilder().GenerateVerificationScripts(scripts)
Expand Down
Loading

0 comments on commit 414172c

Please sign in to comment.