425 lines
12 KiB
Go
425 lines
12 KiB
Go
package repo
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"log"
|
|
"math/big"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/FISCO-BCOS/go-sdk/abi"
|
|
"github.com/FISCO-BCOS/go-sdk/client"
|
|
"github.com/FISCO-BCOS/go-sdk/conf"
|
|
"github.com/FISCO-BCOS/go-sdk/core/types"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/sulenn/trustie-fisco-bcos/contract"
|
|
"github.com/sulenn/trustie-fisco-bcos/contract/opensource"
|
|
"github.com/sulenn/trustie-fisco-bcos/modules/structs"
|
|
api "github.com/sulenn/trustie-fisco-bcos/modules/structs"
|
|
|
|
"gitea.com/macaron/macaron"
|
|
)
|
|
|
|
var ()
|
|
|
|
// Create is to create a repository in blockchain ledger
|
|
func Create(ctx *macaron.Context, opt api.CreateRepoOption, logger *log.Logger) { // 创建项目
|
|
tokenName := opt.TokenName
|
|
owner := opt.Owner
|
|
totalSupply := big.NewInt(int64(opt.TotalSupply))
|
|
token_balance := opt.TokenBalance
|
|
|
|
var usernameArr = []string{}
|
|
var balanceArr = []*big.Int{}
|
|
var curSupply int64 = 0
|
|
for i := 0; i < len(token_balance); i++ {
|
|
username, ok := token_balance[i][0].(string)
|
|
if ok != true {
|
|
ctx.JSON(http.StatusOK, structs.TypeTransferErr)
|
|
return
|
|
}
|
|
usernameArr = append(usernameArr, username)
|
|
balance, ok := token_balance[i][1].(float64)
|
|
curSupply += int64(balance)
|
|
if ok != true {
|
|
ctx.JSON(http.StatusOK, structs.TypeTransferErr)
|
|
return
|
|
}
|
|
balanceArr = append(balanceArr, big.NewInt(int64(balance)))
|
|
}
|
|
|
|
configs, err := conf.ParseConfigFile("config.toml")
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
config := &configs[0]
|
|
|
|
client, err := client.Dial(config)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
|
|
// load the contract
|
|
contractAddress := common.HexToAddress(contract.ContractAddress)
|
|
instance, err := opensource.NewOpenSource(contractAddress, client)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
|
|
openSourceSession := &opensource.OpenSourceSession{Contract: instance, CallOpts: *client.GetCallOpts(), TransactOpts: *client.GetTransactOpts()}
|
|
|
|
tx, receipt, err := openSourceSession.CreateRepo(tokenName, owner, totalSupply, big.NewInt(curSupply), usernameArr, balanceArr) // call Insert API
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
logger.Printf("receipt =================: %v\n", receipt)
|
|
//logger.Printf("receipt.Output[2:] =================: %v\n", receipt.Output[2:])
|
|
logger.Printf("tx sent: %s\n", tx.Hash().Hex())
|
|
// insertedLines, err := strconv.Atoi(receipt.Output[2:])
|
|
code, err := parseOutput(opensource.OpenSourceABI, "createRepo", receipt)
|
|
if err != nil {
|
|
logger.Panic("error when transfer string to int: ", err)
|
|
}
|
|
if code.Int64() > 0 {
|
|
logger.Printf("inserted lines: %v\n", code)
|
|
//ctx.JSON(http.StatusOK, structs.ResRepoSucc)
|
|
ctx.JSON(http.StatusOK, &structs.ResponseTxHash{
|
|
Response: structs.Response{
|
|
Status: 0,
|
|
Message: "create repo successfully!",
|
|
},
|
|
TxHash: tx.Hash().Hex(),
|
|
})
|
|
return
|
|
} else if code.Int64() == contract.RepoExisted {
|
|
logger.Printf("error code: %v, message: %v\n", code, structs.ResRepoExisted)
|
|
ctx.JSON(http.StatusOK, structs.ResRepoExisted)
|
|
return
|
|
} else if code.Int64() == contract.BalanceOverFlow {
|
|
logger.Printf("error code: %v, message: %v\n", code, structs.ResRepoBalanceOverFlow)
|
|
ctx.JSON(http.StatusOK, structs.ResRepoBalanceOverFlow)
|
|
return
|
|
}
|
|
ctx.JSON(http.StatusOK, structs.ResRepoUnsucc)
|
|
}
|
|
|
|
func QueryBasic(ctx *macaron.Context, tokenName string, logger *log.Logger) {
|
|
if tokenName == "" {
|
|
ctx.JSON(http.StatusOK, api.StringEmpty)
|
|
return
|
|
}
|
|
|
|
configs, err := conf.ParseConfigFile("config.toml")
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
config := &configs[0]
|
|
|
|
client, err := client.Dial(config)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
|
|
// load the contract
|
|
contractAddress := common.HexToAddress(contract.ContractAddress)
|
|
instance, err := opensource.NewOpenSource(contractAddress, client)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
|
|
openSourceSession := &opensource.OpenSourceSession{Contract: instance, CallOpts: *client.GetCallOpts(), TransactOpts: *client.GetTransactOpts()}
|
|
|
|
_, owner, totalSupply, curSupply, err := openSourceSession.SelectRepoBasicInfo(tokenName) // call Insert API
|
|
if err != nil {
|
|
ctx.JSON(http.StatusOK, api.UnknownErr(err))
|
|
return
|
|
}
|
|
|
|
fmt.Printf("tokenName: %v, owner: %v, totalSupply: %v, curSupply: %v \n", tokenName, owner, totalSupply, curSupply)
|
|
|
|
ctx.JSON(http.StatusOK, &structs.ReponseRepo{
|
|
Response: structs.Response{
|
|
Status: 0,
|
|
Message: "query success!",
|
|
},
|
|
Repo: structs.Repo{
|
|
TokenName: tokenName,
|
|
Owner: owner,
|
|
TotalSupply: totalSupply.Uint64(),
|
|
CurSupply: curSupply.Uint64(),
|
|
},
|
|
})
|
|
}
|
|
|
|
func parseOutput(abiStr, name string, receipt *types.Receipt) (*big.Int, error) {
|
|
parsed, err := abi.JSON(strings.NewReader(abiStr))
|
|
if err != nil {
|
|
fmt.Printf("parse ABI failed, err: %v", err)
|
|
}
|
|
var ret *big.Int
|
|
b, err := hex.DecodeString(receipt.Output[2:])
|
|
log.Printf("hex.DecodeString receipt.Output[2:] =================: %v\n", b)
|
|
log.Printf("hex.DecodeString receipt.len[2:] =================: %v\n", len(b))
|
|
log.Printf("hex.DecodeString receipt.Output[2:] =================: %v\n", len(b)%32)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decode receipt.Output[2:] failed, err: %v", err)
|
|
}
|
|
err = parsed.Unpack(&ret, name, b)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unpack %v failed, err: %v", name, err)
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
// // Transfer is to transfer amount from one person to another
|
|
// func Transfer(ctx *macaron.Context, opt api.TransferTokenOption) { // 转账
|
|
// tokenSymbol := opt.TokenSymbol
|
|
// from := opt.From
|
|
// to := opt.To
|
|
// amount := fmt.Sprintf("%v", opt.Amount)
|
|
|
|
// chainArgsToJsonString, err := format.ArgsJson("transfer", tokenSymbol, from, to, amount)
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("trasfer:%v", err))
|
|
// return
|
|
// }
|
|
|
|
// err = chaincode.InvokeOther(*chainArgsToJsonString)
|
|
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("trasfer:%v", err))
|
|
// return
|
|
// }
|
|
|
|
// userBalanceList := structs.UserBalanceList{}
|
|
|
|
// payerAmout, err := queryUserBalance(tokenSymbol, from) // 付款人余额信息
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("It is failed when query payer amount: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// payer := &structs.UserBalance{
|
|
// Username: from,
|
|
// TokenSymbol: tokenSymbol,
|
|
// Balance: *payerAmout,
|
|
// }
|
|
// userBalanceList = append(userBalanceList, payer)
|
|
|
|
// payeeAmout, err := queryUserBalance(tokenSymbol, to) // 收款人余额信息
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("It is failed when query payee amount: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// payee := &structs.UserBalance{
|
|
// Username: to,
|
|
// TokenSymbol: tokenSymbol,
|
|
// Balance: *payeeAmout,
|
|
// }
|
|
// userBalanceList = append(userBalanceList, payee)
|
|
|
|
// ctx.JSON(http.StatusOK, userBalanceList)
|
|
// }
|
|
|
|
// // Add is to help user add amount
|
|
// func Add(ctx *macaron.Context, opt api.AddTokenOption) { // 增加用户余额
|
|
// tokenSymbol := opt.TokenSymbol
|
|
// username := opt.Username
|
|
// amount := fmt.Sprintf("%v", opt.Amount)
|
|
|
|
// err := add(tokenSymbol, username, amount)
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("add: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// userAmout, err := queryUserBalance(tokenSymbol, username) // 用户余额信息
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("It is failed when query user amount: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// user := &structs.UserBalance{
|
|
// Username: username,
|
|
// TokenSymbol: tokenSymbol,
|
|
// Balance: *userAmout,
|
|
// }
|
|
|
|
// ctx.JSON(http.StatusOK, user)
|
|
// }
|
|
|
|
// func add(reponame string, username string, amount string) error { // 用户添加余额
|
|
// chainArgsToJsonString, err := format.ArgsJson("add", reponame, username, amount)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
|
|
// err = chaincode.InvokeOther(*chainArgsToJsonString) // 调用 chaincode
|
|
|
|
// return err
|
|
// }
|
|
|
|
// // Minus is to help user minus amount
|
|
// func Minus(ctx *macaron.Context, opt api.MinusTokenOption) { // 减少用户余额
|
|
// tokenSymbol := opt.TokenSymbol
|
|
// username := opt.Username
|
|
// amount := fmt.Sprintf("%v", opt.Amount)
|
|
|
|
// err := minus(tokenSymbol, username, amount)
|
|
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("minus: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// userAmout, err := queryUserBalance(tokenSymbol, username) // 用户余额信息
|
|
// if err != nil {
|
|
// ctx.JSON(http.StatusInternalServerError, err)
|
|
// return
|
|
// }
|
|
|
|
// user := &structs.UserBalance{
|
|
// Username: username,
|
|
// TokenSymbol: tokenSymbol,
|
|
// Balance: *userAmout,
|
|
// }
|
|
|
|
// ctx.JSON(http.StatusOK, user)
|
|
// }
|
|
|
|
// func minus(reponame string, username string, amount string) error {
|
|
// chainArgsToJsonString, err := format.ArgsJson("minus", reponame, username, amount)
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
|
|
// err = chaincode.InvokeOther(*chainArgsToJsonString) // 调用 chaincode
|
|
|
|
// return err
|
|
// }
|
|
|
|
// // QueryUserBalance is to query user balance by reponame and username
|
|
// func QueryUserBalance(ctx *macaron.Context) { // 查询余额
|
|
// reponame := ctx.Query("reponame")
|
|
// if reponame == "" {
|
|
// ctx.JSON(http.StatusPreconditionFailed, "reponame is not nil")
|
|
// return
|
|
// }
|
|
// username := ctx.Query("username")
|
|
// if username == "" {
|
|
// ctx.JSON(http.StatusPreconditionFailed, "username is not nil")
|
|
// return
|
|
// }
|
|
|
|
// amount, err := queryUserBalance(reponame, username)
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("queryUserBalance: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// userBalance := &api.UserBalance{
|
|
// Username: username,
|
|
// TokenSymbol: reponame,
|
|
// Balance: *amount,
|
|
// }
|
|
// ctx.JSON(http.StatusOK, userBalance)
|
|
// }
|
|
|
|
// func queryUserBalance(reponame string, username string) (*uint64, error) { // 查询单次余额
|
|
// chainArgsToJsonString, err := format.ArgsJson("userBalance", reponame, username)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// balance, err := chaincode.InvokeBalance(*chainArgsToJsonString)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// return balance, err
|
|
// }
|
|
|
|
// // QueryRepoAmount is to query repository amount by reponame
|
|
// func QueryRepoAmount(ctx *macaron.Context) { // 查询项目总金额
|
|
// reponame := ctx.Query("reponame")
|
|
// if reponame == "" {
|
|
// ctx.Error(http.StatusPreconditionFailed, "reponame is not nil")
|
|
// return
|
|
// }
|
|
// username := ctx.Query("username")
|
|
|
|
// amount, err := queryRepoAmount(reponame)
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("queryRepoAmount: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// userBalance := &api.Repo{
|
|
// Owner: username,
|
|
// TokenSymbol: reponame,
|
|
// TotalSupply: *amount,
|
|
// }
|
|
// ctx.JSON(http.StatusOK, userBalance)
|
|
// }
|
|
|
|
// func queryRepoAmount(reponame string) (*uint64, error) { // 查询项目总金额
|
|
// chainArgsToJsonString, err := format.ArgsJson("repoAmount", reponame)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// balance, err := chaincode.InvokeBalance(*chainArgsToJsonString)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
|
|
// return balance, err
|
|
// }
|
|
|
|
// // Upload is to record commit info to blockchain
|
|
// func Upload(ctx *macaron.Context, opt api.UploadCommitOption) { // 记录 commit 信息
|
|
// commitString, err := json.Marshal(opt)
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("upload: %v", err))
|
|
// }
|
|
|
|
// chainArgsToJsonString, err := format.ArgsJson("commit", string(commitString)) // 记录 commit 信息
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("upload: %v", err))
|
|
// }
|
|
|
|
// err = chaincode.InvokeOther(*chainArgsToJsonString) // 调用 chaincode
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("upload: %v", err))
|
|
// }
|
|
|
|
// err = add(opt.Reponame, opt.Username, strconv.Itoa(opt.ModificationLines)) // 为用户加钱
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("upload: %v", err))
|
|
// }
|
|
|
|
// userAmout, err := queryUserBalance(opt.Reponame, opt.Username) // 用户余额信息
|
|
// if err != nil {
|
|
// ctx.Error(http.StatusInternalServerError, fmt.Sprintf("It is failed when query user amount: %v", err))
|
|
// return
|
|
// }
|
|
|
|
// user := &structs.UserBalance{
|
|
// Username: opt.Username,
|
|
// TokenSymbol: opt.Reponame,
|
|
// Balance: *userAmout,
|
|
// }
|
|
|
|
// ctx.JSON(http.StatusOK, user)
|
|
|
|
// }
|