Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalplan authored and fractalplan committed Jan 18, 2019
0 parents commit 63feb57
Show file tree
Hide file tree
Showing 1,311 changed files with 426,369 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global

*.a

.DS_Store

# IdeaIDE
.idea

# VS Code
.vscode

ft
!/cmd/ft

ftkey
!/cmd/ftkey
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2018 The Fractal Team Authors
# This file is part of the fractal project.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.

language: go

go:
- 1.9.2

install:
- make test
675 changes: 675 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2018 The Fractal Team Authors
# This file is part of the fractal project.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

TEST = $(shell go list ./... | grep -v test | grep -v txpool)

all:
@go install ./cmd/ft
go build ./cmd/ft
mv ft ./build/bin

@go install ./cmd/ftkey
go build ./cmd/ftkey
mv ftkey ./build/bin

run:
@./build/bin/ft
stop:
clear:
test: all
@echo $(TEST)
go test $(TEST)

.PHONY: all run stop clear test
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# fractal
[![Build Status](https://travis-ci.org/fractalplatform/fractal.svg?branch=master)](https://travis-ci.org/fractalplatform/fractal)
[![GoDoc](https://godoc.org/github.com/fractalplatform/fractal?status.svg)](https://godoc.org/github.com/fractalplatform/fractal)
303 changes: 303 additions & 0 deletions accountmanager/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
// Copyright 2018 The Fractal Team Authors
// This file is part of the fractal project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package accountmanager

import (
"math/big"

"github.com/fractalplatform/fractal/asset"
"github.com/fractalplatform/fractal/common"
"github.com/fractalplatform/fractal/crypto"
)

// AssetBalance asset and balance struct
type AssetBalance struct {
AssetID uint64
Balance *big.Int
}

func newAssetBalance(assetID uint64, amount *big.Int) *AssetBalance {
ab := AssetBalance{
AssetID: assetID,
Balance: amount,
}
return &ab
}

//Account account object
type Account struct {
AcctName common.Name
Nonce uint64
PublicKey common.PubKey
Code []byte
CodeHash common.Hash
CodeSize uint64
//sort by asset id asc
Balances []*AssetBalance
//code Suicide
Suicide bool
//account destroy
Destroy bool
}

// NewAccount create a new account object.
func NewAccount(accountName common.Name, pubkey common.PubKey) (*Account, error) {
//TODO give new accountName func
if !common.IsValidName(accountName.String()) {
return nil, ErrAccountNameInvalid
}

acctObject := Account{
AcctName: accountName,
PublicKey: pubkey,
Nonce: 0,
Balances: make([]*AssetBalance, 0),
Code: make([]byte, 0),
CodeHash: crypto.Keccak256Hash(nil),
Suicide: false,
Destroy: false,
}
return &acctObject, nil
}

func (a *Account) IsEmpty() bool {
if a.GetCodeSize() == 0 && len(a.Balances) == 0 && a.Nonce == 0 {
return true
}
return false
}

// GetName return account object name
func (a *Account) GetName() common.Name {
return a.AcctName
}

// GetNonce get nonce
func (a *Account) GetNonce() uint64 {
return a.Nonce
}

// SetNonce set nonce
func (a *Account) SetNonce(nonce uint64) {
a.Nonce = nonce
}

//GetPubKey get bugkey
func (a *Account) GetPubKey() common.PubKey {
return a.PublicKey
}

//SetPubKey set pub key
func (a *Account) SetPubKey(pubkey common.PubKey) {
a.PublicKey.SetBytes(pubkey.Bytes())
}

//GetCode get code
func (a *Account) GetCode() ([]byte, error) {
if a.CodeSize == 0 || a.Suicide {
return nil, ErrCodeIsEmpty
}
return a.Code, nil
}

// GetCodeSize get code size
func (a *Account) GetCodeSize() uint64 {
return a.CodeSize
}

// SetCode set code
func (a *Account) SetCode(code []byte) error {
if len(code) == 0 {
return ErrCodeIsEmpty
}
a.Code = code
a.CodeHash = crypto.Keccak256Hash(code)
a.CodeSize = uint64(len(code))
return nil
}

// GetCodeHash get code hash
func (a *Account) GetCodeHash() (common.Hash, error) {
if len(a.CodeHash) == 0 {
return common.Hash{}, ErrHashIsEmpty
}
return a.CodeHash, nil
}

//GetBalanceByID get balance by asset id
func (a *Account) GetBalanceByID(assetID uint64) (*big.Int, error) {
if assetID == 0 {
return big.NewInt(0), ErrAssetIDInvalid
}
if p, find := a.binarySearch(assetID); find == true {
return a.Balances[p].Balance, nil
}
return big.NewInt(0), ErrAccountAssetNotExist
}

//GetBalancesList get all balance list
func (a *Account) GetBalancesList() []*AssetBalance {
return a.Balances
}

//GetAllBalances get all balance list
func (a *Account) GetAllBalances() (map[uint64]*big.Int, error) {
var ba = make(map[uint64]*big.Int, 0)
for _, ab := range a.Balances {
ba[ab.AssetID] = ab.Balance
}
return ba, nil
}

// BinarySearch binary search
func (a *Account) binarySearch(assetID uint64) (int64, bool) {
if len(a.Balances) == 0 {
return 0, false
}
low := int64(0)
high := int64(len(a.Balances)) - 1

for low <= high {
mid := (low + high) / 2
if a.Balances[mid].AssetID < assetID {
low = mid + 1
} else if a.Balances[mid].AssetID > assetID {
high = mid - 1
} else if a.Balances[mid].AssetID == assetID {
return mid, true
}
}
if high < 0 {
high = 0
}
return high, false
}

//AddNewAssetByAssetID add a new asset to balance list and set the value to zero
func (a *Account) AddNewAssetByAssetID(assetID uint64, amount *big.Int) {
//TODO dest account can recv asset
p, find := a.binarySearch(assetID)
if find {
a.Balances[p].Balance = amount
} else {
//append
if len(a.Balances) == 0 || ((a.Balances[p].AssetID < assetID) && (p+1 == int64(len(a.Balances)))) {
a.Balances = append(a.Balances, newAssetBalance(assetID, amount))
} else {
//insert
if a.Balances[p].AssetID < assetID {
//insert back
p = p + 1
tail := append([]*AssetBalance{}, a.Balances[p:]...)
a.Balances = append(a.Balances[:p], newAssetBalance(assetID, amount))
a.Balances = append(a.Balances, tail...)
} else {
//insert front
if len(a.Balances) > 1 {
if a.Balances[p].AssetID < assetID {
p = p + 1
}
tail := append([]*AssetBalance{}, a.Balances[p:]...)
a.Balances = append(a.Balances[:p], newAssetBalance(assetID, amount))
a.Balances = append(a.Balances, tail...)
} else {
tail := append([]*AssetBalance{}, a.Balances[p:]...)
a.Balances = append([]*AssetBalance{}, newAssetBalance(assetID, amount))
a.Balances = append(a.Balances, tail...)
}
}
}
}
return
}

//SetBalance set amount to balance
func (a *Account) SetBalance(assetID uint64, amount *big.Int) error {
p, find := a.binarySearch(assetID)
if find {
a.Balances[p].Balance = amount
return nil
}
return asset.ErrAssetNotExist
}

func (a *Account) SubBalanceByID(assetID uint64, value *big.Int) error {
if value.Cmp(big.NewInt(0)) < 0 {
return ErrAmountValueInvalid
}
val, err := a.GetBalanceByID(assetID)
if err != nil {
return err
}
if val.Cmp(big.NewInt(0)) < 0 || val.Cmp(value) < 0 {
return ErrInsufficientBalance
}
a.SetBalance(assetID, new(big.Int).Sub(val, value))
return nil
}

//AddAccountBalanceByID add balance by assetID
func (a *Account) AddBalanceByID(assetID uint64, value *big.Int) error {
if value.Cmp(big.NewInt(0)) < 0 {
return ErrAmountValueInvalid
}
val, err := a.GetBalanceByID(assetID)
if err == ErrAccountAssetNotExist {
a.AddNewAssetByAssetID(assetID, value)
} else {
a.SetBalance(assetID, new(big.Int).Add(val, value))
}
return nil
}

func (a *Account) EnoughAccountBalance(assetID uint64, value *big.Int) error {
if value.Cmp(big.NewInt(0)) < 0 {
return ErrAmountValueInvalid
}

val, err := a.GetBalanceByID(assetID)
if err != nil {
return err
}
if val.Cmp(value) < 0 {
return ErrInsufficientBalance
}
return nil
}

// IsSuicided suicide
func (a *Account) IsSuicided() bool {
return a.Suicide
}

// SetSuicide set setSuicide
func (a *Account) SetSuicide() {
//just make a sign now
a.CodeSize = 0
a.Suicide = true
}

//IsDestoryed is destoryed
func (a *Account) IsDestoryed() bool {
return a.Destroy
}

//SetDestory set destory
func (a *Account) SetDestory() {
//just make a sign now
a.Destroy = true
}
Loading

0 comments on commit 63feb57

Please sign in to comment.