func PermissionJob(perm *definitions.Permission, do *definitions.Do) (string, error) { // Process Variables perm.Source, _ = util.PreProcess(perm.Source, do) perm.Action, _ = util.PreProcess(perm.Action, do) perm.PermissionFlag, _ = util.PreProcess(perm.PermissionFlag, do) perm.Value, _ = util.PreProcess(perm.Value, do) perm.Target, _ = util.PreProcess(perm.Target, do) perm.Role, _ = util.PreProcess(perm.Role, do) // Set defaults perm.Source = useDefault(perm.Source, do.Package.Account) log.Debug("Target: ", perm.Target) log.Debug("Marmots Deny: ", perm.Role) log.Debug("Action: ", perm.Action) // Populate the transaction appropriately var args []string switch perm.Action { case "set_global": args = []string{perm.PermissionFlag, perm.Value} case "set_base": args = []string{perm.Target, perm.PermissionFlag, perm.Value} case "unset_base": args = []string{perm.Target, perm.PermissionFlag} case "add_role", "rm_role": args = []string{perm.Target, perm.Role} } // Don't use pubKey if account override var oldKey string if perm.Source != do.Package.Account { oldKey = do.PublicKey do.PublicKey = "" } // Formulate tx arg := fmt.Sprintf("%s:%s", args[0], args[1]) log.WithField(perm.Action, arg).Info("Setting Permissions") erisNodeClient := client.NewErisNodeClient(do.Chain) erisKeyClient := keys.NewErisKeyClient(do.Signer) tx, err := core.Permissions(erisNodeClient, erisKeyClient, do.PublicKey, perm.Source, perm.Nonce, perm.Action, args) if err != nil { return util.MintChainErrorHandler(do, err) } log.Debug("What are the args returned in transaction: ", tx.PermArgs) // Don't use pubKey if account override if perm.Source != do.Package.Account { do.PublicKey = oldKey } // Sign, broadcast, display return txFinalize(do, tx, perm.Wait) }
// This is a closer function which is called by most of the tx_run functions func ReadTxSignAndBroadcast(result *core.TxResult, err error) error { // if there's an error just return. if err != nil { return err } // if there is nothing to unpack then just return. if result == nil { return nil } // Unpack and display for the user. addr := fmt.Sprintf("%X", result.Address) hash := fmt.Sprintf("%X", result.Hash) blkHash := fmt.Sprintf("%X", result.BlockHash) ret := fmt.Sprintf("%X", result.Return) if result.Address != nil { log.WithField("addr", addr).Warn() log.WithField("txHash", hash).Info() } else { log.WithField("=>", hash).Warn("Transaction Hash") log.WithField("=>", blkHash).Debug("Block Hash") if len(result.Return) != 0 { if ret != "" { log.WithField("=>", ret).Warn("Return Value") } else { log.Debug("No return.") } log.WithField("=>", result.Exception).Debug("Exception") } } return nil }
func makeRaw(do *definitions.Do, typ string) error { accountTypes, err := LoadAccountTypes() if err != nil { return err } log.Debug("Account types loaded.") if err := assembleTypesRaw(accountTypes, do, typ); err != nil { return err } return maker(do, "mint", accountTypes) }
func GetReturnValue(vars []*definitions.Variable) string { var result []string if len(vars) > 1 { for _, value := range vars { log.WithField("=>", []byte(value.Value)).Debug("Value") result = append(result, value.Value) } return "(" + strings.Join(result, ", ") + ")" } else if len(vars) == 1 { log.Debug("Debugging: ", vars[0].Value) return vars[0].Value } else { return "" } }
func numReturns(abiSpec ABI, methodName string) (uint, error) { method, exist := abiSpec.Methods[methodName] if !exist { if methodName == "()" { return 0, nil } return 0, fmt.Errorf("method '%s' not found", methodName) } if len(method.Outputs) == 0 { log.Debug("Empty output, nothing to interface to") return 0, nil } else if len(method.Outputs) == 1 { return 1, nil } else { return 2, nil } }
func QueryValsJob(query *definitions.QueryVals, do *definitions.Do) (string, error) { var result string // Preprocess variables query.Field, _ = util.PreProcess(query.Field, do) // Peform query log.WithField("=>", query.Field).Info("Querying Vals") result, err := util.ValidatorsInfo(query.Field, do) if err != nil { return "", err } if result != "" { log.WithField("=>", result).Warn("Return Value") } else { log.Debug("No return.") } return result, nil }
func QueryAccountJob(query *definitions.QueryAccount, do *definitions.Do) (string, error) { // Preprocess variables query.Account, _ = util.PreProcess(query.Account, do) query.Field, _ = util.PreProcess(query.Field, do) // Perform Query arg := fmt.Sprintf("%s:%s", query.Account, query.Field) log.WithField("=>", arg).Info("Querying Account") result, err := util.AccountsInfo(query.Account, query.Field, do) if err != nil { return "", err } // Result if result != "" { log.WithField("=>", result).Warn("Return Value") } else { log.Debug("No return.") } return result, nil }
func QueryNameJob(query *definitions.QueryName, do *definitions.Do) (string, error) { // Preprocess variables query.Name, _ = util.PreProcess(query.Name, do) query.Field, _ = util.PreProcess(query.Field, do) // Peform query log.WithFields(log.Fields{ "name": query.Name, "field": query.Field, }).Info("Querying") result, err := util.NamesInfo(query.Name, query.Field, do) if err != nil { return "", err } if result != "" { log.WithField("=>", result).Warn("Return Value") } else { log.Debug("No return.") } return result, nil }
func PreProcessInputData(function string, data interface{}, do *definitions.Do, constructor bool) (string, []string, error) { var callDataArray []string var callArray []string if function == "" && !constructor { if reflect.TypeOf(data).Kind() == reflect.Slice { return "", []string{""}, fmt.Errorf("Incorrect formatting of epm run file. Please update your epm run file to include a function field.") } log.Warn("Deprecation Warning: The use of the 'data' field to specify the name of the contract function has been deprecated. Please update your epm jobs file to utilize a combination of 'function' and 'data' fields instead. See documentation for further details.") function = strings.Split(data.(string), " ")[0] callArray = strings.Split(data.(string), " ")[1:] for _, val := range callArray { output, _ := PreProcess(val, do) callDataArray = append(callDataArray, output) } } else if data != nil { if reflect.TypeOf(data).Kind() != reflect.Slice { if constructor { log.Warn("Deprecation Warning: Your deploy job is currently using a soon to be deprecated way of declaring constructor values. Please remember to update your run file to store them as a array rather than a string. See documentation for further details.") callArray = strings.Split(data.(string), " ") for _, val := range callArray { output, _ := PreProcess(val, do) callDataArray = append(callDataArray, output) } return function, callDataArray, nil } else { return "", make([]string, 0), fmt.Errorf("Incorrect formatting of epm run file. Please update your epm run file to include a function field.") } } val := reflect.ValueOf(data) for i := 0; i < val.Len(); i++ { s := val.Index(i) var newString string switch s.Interface().(type) { case bool: newString = strconv.FormatBool(s.Interface().(bool)) case int, int32, int64: newString = strconv.FormatInt(int64(s.Interface().(int)), 10) case []interface{}: var args []string for _, index := range s.Interface().([]interface{}) { value := reflect.ValueOf(index) var stringified string switch value.Kind() { case reflect.Int: stringified = strconv.FormatInt(value.Int(), 10) case reflect.String: stringified = value.String() } index, _ = PreProcess(stringified, do) args = append(args, stringified) } newString = "[" + strings.Join(args, ",") + "]" log.Debug(newString) default: newString = s.Interface().(string) } newString, _ = PreProcess(newString, do) callDataArray = append(callDataArray, newString) } } return function, callDataArray, nil }
func CallJob(call *definitions.Call, do *definitions.Do) (string, []*definitions.Variable, error) { var err error var callData string var callDataArray []string // Preprocess variables call.Source, _ = util.PreProcess(call.Source, do) call.Destination, _ = util.PreProcess(call.Destination, do) //todo: find a way to call the fallback function here call.Function, callDataArray, err = util.PreProcessInputData(call.Function, call.Data, do, false) if err != nil { return "", make([]*definitions.Variable, 0), err } call.Function, _ = util.PreProcess(call.Function, do) call.Amount, _ = util.PreProcess(call.Amount, do) call.Nonce, _ = util.PreProcess(call.Nonce, do) call.Fee, _ = util.PreProcess(call.Fee, do) call.Gas, _ = util.PreProcess(call.Gas, do) call.ABI, _ = util.PreProcess(call.ABI, do) // Use default call.Source = useDefault(call.Source, do.Package.Account) call.Amount = useDefault(call.Amount, do.DefaultAmount) call.Fee = useDefault(call.Fee, do.DefaultFee) call.Gas = useDefault(call.Gas, do.DefaultGas) // formulate call var packedBytes []byte if call.ABI == "" { packedBytes, err = util.ReadAbiFormulateCall(call.Destination, call.Function, callDataArray, do) callData = hex.EncodeToString(packedBytes) } else { packedBytes, err = util.ReadAbiFormulateCall(call.ABI, call.Function, callDataArray, do) callData = hex.EncodeToString(packedBytes) } if err != nil { if call.Function == "()" { log.Warn("Calling the fallback function") } else { var str, err = util.ABIErrorHandler(do, err, call, nil) return str, make([]*definitions.Variable, 0), err } } // Don't use pubKey if account override var oldKey string if call.Source != do.Package.Account { oldKey = do.PublicKey do.PublicKey = "" } log.WithFields(log.Fields{ "destination": call.Destination, "function": call.Function, "data": callData, }).Info("Calling") erisNodeClient := client.NewErisNodeClient(do.Chain) erisKeyClient := keys.NewErisKeyClient(do.Signer) tx, err := core.Call(erisNodeClient, erisKeyClient, do.PublicKey, call.Source, call.Destination, call.Amount, call.Nonce, call.Gas, call.Fee, callData) if err != nil { return "", make([]*definitions.Variable, 0), err } // Don't use pubKey if account override if call.Source != do.Package.Account { do.PublicKey = oldKey } // Sign, broadcast, display res, err := core.SignAndBroadcast(do.ChainID, erisNodeClient, erisKeyClient, tx, true, true, call.Wait) if err != nil { var str, err = util.MintChainErrorHandler(do, err) return str, make([]*definitions.Variable, 0), err } txResult := res.Return var result string log.Debug(txResult) // Formally process the return if txResult != nil { log.WithField("=>", result).Debug("Decoding Raw Result") if call.ABI == "" { call.Variables, err = util.ReadAndDecodeContractReturn(call.Destination, call.Function, txResult, do) } else { call.Variables, err = util.ReadAndDecodeContractReturn(call.ABI, call.Function, txResult, do) } if err != nil { return "", make([]*definitions.Variable, 0), err } log.WithField("=>", call.Variables).Debug("call variables:") result = util.GetReturnValue(call.Variables) if result != "" { log.WithField("=>", result).Warn("Return Value") } else { log.Debug("No return.") } } else { log.Debug("No return from contract.") } if call.Save == "tx" { log.Info("Saving tx hash instead of contract return") result = fmt.Sprintf("%X", res.Hash) } return result, call.Variables, nil }
func deployContract(deploy *definitions.Deploy, do *definitions.Do, r response.ResponseItem, p string) (string, error) { log.WithField("=>", string(r.ABI)).Debug("ABI Specification (From Compilers)") contractCode := r.Bytecode // Save ABI if _, err := os.Stat(do.ABIPath); os.IsNotExist(err) { if err := os.Mkdir(do.ABIPath, 0775); err != nil { return "", err } } // saving contract/library abi var abiLocation string if r.Objectname != "" { abiLocation = filepath.Join(do.ABIPath, r.Objectname) log.WithField("=>", abiLocation).Debug("Saving ABI") if err := ioutil.WriteFile(abiLocation, []byte(r.ABI), 0664); err != nil { return "", err } } else { log.Debug("Objectname from compilers is blank. Not saving abi.") } // saving binary if deploy.SaveBinary { contractDir := filepath.Dir(deploy.Contract) contractName := filepath.Join(contractDir, fmt.Sprintf("%s.bin", strings.TrimSuffix(deploy.Contract, filepath.Ext(deploy.Contract)))) log.WithField("=>", contractName).Info("Saving Binary") if err := ioutil.WriteFile(contractName, []byte(contractCode), 0664); err != nil { return "", err } } else { log.Debug("Not saving binary.") } // additional data may be sent along with the contract // these are naively added to the end of the contract code using standard // mint packing if deploy.Data != nil { _, callDataArray, err := util.PreProcessInputData(r.Objectname, deploy.Data, do, true) if err != nil { return "", err } packedBytes, err := util.ReadAbiFormulateCall(r.Objectname, "", callDataArray, do) if err != nil { return "", err } callData := hex.EncodeToString(packedBytes) contractCode = contractCode + callData } tx, err := deployRaw(do, deploy, r.Objectname, contractCode) if err != nil { return "", err } // Sign, broadcast, display result, err := deployFinalize(do, tx, deploy.Wait) if err != nil { return "", fmt.Errorf("Error finalizing contract deploy %s: %v", p, err) } // saving contract/library abi at abi/address if result != "" { abiLocation := filepath.Join(do.ABIPath, result) log.WithField("=>", abiLocation).Debug("Saving ABI") if err := ioutil.WriteFile(abiLocation, []byte(r.ABI), 0664); err != nil { return "", err } } else { // we shouldn't reach this point because we should have an error before this. log.Error("The contract did not deploy. Unable to save abi to abi/contractAddress.") } return result, err }
func QueryContractJob(query *definitions.QueryContract, do *definitions.Do) (string, []*definitions.Variable, error) { // Preprocess variables. We don't preprocess data as it is processed by ReadAbiFormulateCall query.Source, _ = util.PreProcess(query.Source, do) query.Destination, _ = util.PreProcess(query.Destination, do) query.ABI, _ = util.PreProcess(query.ABI, do) var queryDataArray []string var err error query.Function, queryDataArray, err = util.PreProcessInputData(query.Function, query.Data, do, false) if err != nil { return "", make([]*definitions.Variable, 0), err } // Set the from and the to fromAddrBytes, err := hex.DecodeString(query.Source) if err != nil { return "", make([]*definitions.Variable, 0), err } toAddrBytes, err := hex.DecodeString(query.Destination) if err != nil { return "", make([]*definitions.Variable, 0), err } // Get the packed data from the ABI functions var data string var packedBytes []byte if query.ABI == "" { packedBytes, err = util.ReadAbiFormulateCall(query.Destination, query.Function, queryDataArray, do) data = hex.EncodeToString(packedBytes) } else { packedBytes, err = util.ReadAbiFormulateCall(query.ABI, query.Function, queryDataArray, do) data = hex.EncodeToString(packedBytes) } if err != nil { var str, err = util.ABIErrorHandler(do, err, nil, query) return str, make([]*definitions.Variable, 0), err } dataBytes, err := hex.DecodeString(data) if err != nil { return "", make([]*definitions.Variable, 0), err } // Call the client nodeClient := client.NewErisNodeClient(do.Chain) result, _, err := nodeClient.QueryContract(fromAddrBytes, toAddrBytes, dataBytes) if err != nil { return "", make([]*definitions.Variable, 0), err } // Formally process the return log.WithField("res", result).Debug("Decoding Raw Result") if query.ABI == "" { log.WithField("abi", query.Destination).Debug() query.Variables, err = util.ReadAndDecodeContractReturn(query.Destination, query.Function, result, do) } else { log.WithField("abi", query.ABI).Debug() query.Variables, err = util.ReadAndDecodeContractReturn(query.ABI, query.Function, result, do) } if err != nil { return "", make([]*definitions.Variable, 0), err } result2 := util.GetReturnValue(query.Variables) // Finalize if result2 != "" { log.WithField("=>", result2).Warn("Return Value") } else { log.Debug("No return.") } return result2, query.Variables, nil }