func SetAccountJob(account *definitions.Account, do *definitions.Do) (string, error) { var result string var err error // Preprocess account.Address, _ = util.PreProcess(account.Address, do) // Set the Account in the Package & Announce do.Package.Account = account.Address log.WithField("=>", do.Package.Account).Info("Setting Account") // Set the public key from eris-keys keys.DaemonAddr = do.Signer log.WithField("from", keys.DaemonAddr).Info("Getting Public Key") do.PublicKey, err = keys.Call("pub", map[string]string{"addr": do.Package.Account, "name": ""}) if _, ok := err.(keys.ErrConnectionRefused); ok { keys.ExitConnectErr(err) } if err != nil { return util.KeysErrorHandler(do, err) } // Set result and return result = account.Address return result, nil }
func assembleTypesWizard(accountT *definitions.AccountType, tokenIze bool) error { var err error accountT.Number, err = common.GetIntResponse(AccountTypeIntro(accountT), accountT.Number, reader) log.WithField("=>", accountT.Number).Debug("What the marmots heard") if err != nil { return err } if tokenIze && accountT.Number > 0 { accountT.Tokens, err = common.GetIntResponse(AccountTypeTokens(accountT), accountT.Tokens, reader) log.WithField("=>", accountT.Tokens).Debug("What the marmots heard") if err != nil { return err } } if accountT.Perms["bond"] == 1 && accountT.Number > 0 { accountT.ToBond, err = common.GetIntResponse(AccountTypeToBond(accountT), accountT.ToBond, reader) log.WithField("=>", accountT.ToBond).Debug("What the marmots heard") if err != nil { return err } } else { log.Info("Setting accountType.ToBond to 0") log.WithField("=>", accountT.Name).Debug("No bond permissions") accountT.ToBond = 0 } return nil }
// ensures that the files which are included in this repository (`defaultTyps`) are also // present in the user's .eris/chains/account_types directory. // // does not ensure that the contents of the files are the same so will not affect user // defined settings around these files. // // does not check if the user has more account_types files in their .eris/chains/account_types // directory either so users can safely add additional account_types beyond the marmot // established defaults. func CheckDefaultTypes(erisPath, myPath string) error { // by default the dockerimage will move the default files to /default // however if anyone installs by binary then these files will be located // in the repo. defaultTypsPath := filepath.Join("/defaults", myPath, "*.toml") if _, err := os.Stat(filepath.Dir(defaultTypsPath)); os.IsNotExist(err) { log.WithField("path", defaultTypsPath).Warn("Default types path does not exist. Trying GOPATH.") defaultTypsPath = filepath.Join(ErisGo, version.NAME, myPath, "*.toml") } if _, err := os.Stat(filepath.Dir(defaultTypsPath)); os.IsNotExist(err) { log.WithField("path", defaultTypsPath).Info("Default types path does not exist. Exiting.") return fmt.Errorf("Could not locate default directory for %s", myPath) } // files in the default location which is /defaults in the docker image and $GOPATH/src/github.com/.../ // if binary install defaultTyps, err := filepath.Glob(defaultTypsPath) if err != nil { return err } // these are files which are in ~/.eris/chains/XXXXX and imported to the data container // by cli haveTyps, err := AccountTypesNames(erisPath, true) if err != nil { return err } // fail fast if there are not files present in either imported or in default directory if len(defaultTyps) == 0 && len(haveTyps) == 0 { return fmt.Errorf("There are no default or custom types to use.") } for _, file := range defaultTyps { f := filepath.Base(file) itsThere := false // check if present for _, b := range haveTyps { if f == b { itsThere = true } } if !itsThere { log.WithFields(log.Fields{ "file": file, "path": filepath.Join(erisPath, f), }).Debug("Copying default file") Copy(file, filepath.Join(erisPath, f)) } } return nil }
func replaceBlockVariable(toReplace string, do *definitions.Do) (string, error) { log.WithFields(log.Fields{ "chain": do.Chain, "var": toReplace, }).Debug("Correcting $block variable") blockHeight, err := GetBlockHeight(do) block := strconv.Itoa(blockHeight) log.WithField("=>", block).Debug("Current height is") if err != nil { return "", err } if toReplace == "$block" { log.WithField("=>", block).Debug("Replacement (=)") return block, nil } catchEr := regexp.MustCompile("\\$block\\+(\\d*)") if catchEr.MatchString(toReplace) { height := catchEr.FindStringSubmatch(toReplace)[1] h1, err := strconv.Atoi(height) if err != nil { return "", err } h2, err := strconv.Atoi(block) if err != nil { return "", err } height = strconv.Itoa(h1 + h2) log.WithField("=>", height).Debug("Replacement (+)") return height, nil } catchEr = regexp.MustCompile("\\$block\\-(\\d*)") if catchEr.MatchString(toReplace) { height := catchEr.FindStringSubmatch(toReplace)[1] h1, err := strconv.Atoi(height) if err != nil { return "", err } h2, err := strconv.Atoi(block) if err != nil { return "", err } height = strconv.Itoa(h1 - h2) log.WithField("=>", height).Debug("Replacement (-)") return height, nil } log.WithField("=>", toReplace).Debug("Replacement (unknown)") return toReplace, nil }
func MakeAccounts(name, chainType string, accountTypes []*definitions.AccountType) ([]*definitions.Account, error) { accounts := []*definitions.Account{} for _, accountT := range accountTypes { log.WithField("type", accountT.Name).Info("Making Account Type") perms := &definitions.MintAccountPermissions{} var err error if chainType == "mint" { perms, err = MintAccountPermissions(accountT.Perms, []string{}) // TODO: expose roles if err != nil { return nil, err } } for i := 0; i < accountT.Number; i++ { thisAct := &definitions.Account{} thisAct.Name = fmt.Sprintf("%s_%s_%03d", name, accountT.Name, i) thisAct.Name = strings.ToLower(thisAct.Name) log.WithField("name", thisAct.Name).Debug("Making Account") thisAct.Tokens = accountT.Tokens thisAct.ToBond = accountT.ToBond thisAct.PermissionsMap = accountT.Perms thisAct.Validator = false if thisAct.ToBond != 0 { thisAct.Validator = true } if chainType == "mint" { thisAct.MintPermissions = &definitions.MintAccountPermissions{} thisAct.MintPermissions.MintBase = &definitions.MintBasePermissions{} thisAct.MintPermissions.MintBase.MintPerms = perms.MintBase.MintPerms thisAct.MintPermissions.MintBase.MintSetBit = perms.MintBase.MintSetBit thisAct.MintPermissions.MintRoles = perms.MintRoles log.WithField("perms", thisAct.MintPermissions.MintBase.MintPerms).Debug() if err := makeKey("ed25519,ripemd160", thisAct); err != nil { return nil, err } } accounts = append(accounts, thisAct) } } return accounts, nil }
func makeKey(keyType string, account *definitions.Account) error { log.WithFields(log.Fields{ "path": keys.DaemonAddr, "type": keyType, }).Debug("Sending Call to eris-keys server") var err error log.WithField("endpoint", "gen").Debug() account.Address, err = keys.Call("gen", map[string]string{"auth": "", "type": keyType, "name": account.Name}) // note, for now we use not password to lock/unlock keys if _, ok := err.(keys.ErrConnectionRefused); ok { return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err) } if err != nil { return err } log.WithField("endpoint", "pub").Debug() account.PubKey, err = keys.Call("pub", map[string]string{"addr": account.Address, "name": account.Name}) if _, ok := err.(keys.ErrConnectionRefused); ok { return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err) } if err != nil { return err } // log.WithField("endpoint", "to-mint").Debug() // mint, err := keys.Call("to-mint", map[string]string{"addr": account.Address, "name": account.Name}) log.WithField("endpoint", "mint").Debug() mint, err := keys.Call("mint", map[string]string{"addr": account.Address, "name": account.Name}) if _, ok := err.(keys.ErrConnectionRefused); ok { return fmt.Errorf("Could not connect to eris-keys server. Start it with `eris services start keys`. Error: %v", err) } if err != nil { return err } account.MintKey = &definitions.MintPrivValidator{} err = json.Unmarshal([]byte(mint), account.MintKey) if err != nil { log.Error(string(mint)) log.Error(account.MintKey) return err } account.MintKey.Address = account.Address return nil }
func WriteConfigurationFile(chain_name, account_name, seeds string, single bool, chainImageName string, useDataContainer bool, exportedPorts []string, containerEntrypoint string) error { if account_name == "" { account_name = "anonymous_marmot" } if chain_name == "" { return fmt.Errorf("No chain name provided.") } var fileBytes []byte var err error if fileBytes, err = configuration.GetConfigurationFileBytes(chain_name, account_name, seeds, chainImageName, useDataContainer, convertExportPortsSliceToString(exportedPorts), containerEntrypoint); err != nil { return err } var file string if !single { file = filepath.Join(ChainsPath, chain_name, account_name, "config.toml") } else { file = filepath.Join(ChainsPath, chain_name, "config.toml") } log.WithField("path", file).Debug("Saving File.") if err := WriteFile(string(fileBytes), file); err != nil { return err } return nil }
func SetValJob(set *definitions.Set, do *definitions.Do) (string, error) { var result string set.Value, _ = util.PreProcess(set.Value, do) log.WithField("=>", set.Value).Info("Setting Variable") result = set.Value return result, nil }
func makeWizard(do *definitions.Do) error { proceed, err := common.GetBoolResponse(ChainsMakeWelcome(), true, os.Stdin) log.WithField("=>", proceed).Debug("What the marmots heard") if err != nil { return err } if !proceed { log.Warn("The marmots will not proceed without your authorization. Exiting.") return nil } prelims := make(map[string]bool) for e, q := range ChainsMakePrelimQuestions() { prelims[e], err = common.GetBoolResponse(q, false, os.Stdin) log.WithField("=>", prelims[e]).Debug("What the marmots heard") if err != nil { return err } } accountTypes, err := LoadAccountTypes() if err != nil { return err } for _, accountT := range accountTypes { if err := assembleTypesWizard(accountT, prelims["tokens"]); err != nil { return err } } if prelims["dryrun"] { // todo check if procede or return.... } if prelims["manual"] { var err error accountTypes, err = addManualAccountType(accountTypes, 0) if err != nil { return err } } return maker(do, "mint", accountTypes) }
func assembleTypesCSV(accountT []*definitions.AccountType, do *definitions.Do) error { clearDefaultNumbers(accountT) csvfile, err := os.Open(do.CSV) if err != nil { return err } defer csvfile.Close() reader := csv.NewReader(csvfile) reader.TrimLeadingSpace = true rawCSVdata, err := reader.ReadAll() if err != nil { return err } log.WithField("rawCSVdata", rawCSVdata).Debug("Data read.") for _, record := range rawCSVdata { act, num, tokens, toBond, perms := record[0], record[1], record[2], record[3], record[4:] for _, thisActT := range accountT { if thisActT.Name == act { var err error thisActT.Number, err = strconv.Atoi(num) if err != nil { return err } thisActT.Tokens, err = strconv.Atoi(tokens) if err != nil { return err } thisActT.ToBond, err = strconv.Atoi(toBond) if err != nil { return err } permsPrime := make(map[string]int) for i := 0; i < len(perms); i++ { p, err := strconv.Atoi(perms[i+1]) if err != nil { return err } permsPrime[perms[i]] = p i++ } thisActT.Perms = permsPrime log.WithFields(log.Fields{ "name": thisActT.Name, "number": thisActT.Number, "tokens": thisActT.Tokens, "toBond": thisActT.ToBond, "perms": thisActT.Perms, }).Debug("Setting Account Type Number") } } } return nil }
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) }
func ReadAndDecodeContractReturn(abiLocation, funcName string, resultRaw []byte, do *definitions.Do) ([]*definitions.Variable, error) { abiSpecBytes, err := readAbi(do.ABIPath, abiLocation) if err != nil { return nil, err } log.WithField("=>", abiSpecBytes).Debug("ABI Specification (Decode)") // Unpack the result return ebi.Unpacker(abiSpecBytes, funcName, resultRaw) }
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 }
// 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 ReadAbiFormulateCall(abiLocation string, funcName string, args []string, do *definitions.Do) ([]byte, error) { abiSpecBytes, err := readAbi(do.ABIPath, abiLocation) if err != nil { return []byte{}, err } log.WithField("=>", string(abiSpecBytes)).Debug("ABI Specification (Formulate)") log.WithFields(log.Fields{ "function": funcName, "arguments": fmt.Sprintf("%v", args), }).Debug("Packing Call via ABI") return ebi.Packer(abiSpecBytes, funcName, args...) }
// TODO: it is unpreferable to mix static and non-static use of Do func GetChainID(do *definitions.Do) error { if do.ChainID == "" { nodeClient := client.NewErisNodeClient(do.Chain) _, chainId, _, err := nodeClient.ChainId() if err != nil { return err } do.ChainID = chainId log.WithField("=>", do.ChainID).Info("Using ChainID from Node") } return 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 PreProcessLibs(libs string, do *definitions.Do) (string, error) { libraries, _ := PreProcess(libs, do) if libraries != "" { pairs := strings.Split(libraries, ",") for _, pair := range pairs { libAndAddr := strings.Split(pair, ":") libAndAddr[1] = strings.ToLower(libAndAddr[1]) pair = strings.Join(libAndAddr, ":") } libraries = strings.Join(pairs, " ") } log.WithField("=>", libraries).Debug("Library String") return libraries, nil }
func LoadAccountTypes() ([]*definitions.AccountType, error) { loadedAccounts := []*definitions.AccountType{} accounts, err := util.AccountTypes(AccountsTypePath) if err != nil { return nil, err } for _, account := range accounts { thisAct, err := LoadAccountType(account) if err != nil { return nil, err } log.WithField("=>", thisAct.Name).Debug("Loaded Account Named") loadedAccounts = append(loadedAccounts, thisAct) } return loadedAccounts, nil }
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 LoadAccountType(fileName string) (*definitions.AccountType, error) { log.WithField("=>", fileName).Debug("Loading Account Type") var accountType = viper.New() typ := definitions.BlankAccountType() if err := getSetup(fileName, accountType); err != nil { return nil, err } // marshall file if err := accountType.Unmarshal(typ); err != nil { return nil, fmt.Errorf("\nSorry, the marmots could not figure that account types file out.\nPlease check your account type definition file is properly formatted.\nERROR =>\t\t\t%v", err) } return typ, nil }
func LoadChainTypes(fileName string) (*definitions.ChainType, error) { fileName = filepath.Join(ChainTypePath, fileName) log.WithField("file name", fileName).Info("Loading Chain Definition.") var typ = definitions.BlankChainType() var chainType = viper.New() if err := getSetup(fileName, chainType); err != nil { return nil, err } // marshall file if err := chainType.Unmarshal(typ); err != nil { return nil, fmt.Errorf("\nSorry, the marmots could not figure that chain types file out.\nPlease check your chain type definition file is properly formatted.\nERROR =>\t\t\t%v", err) } return typ, nil }
func writer(toWrangle interface{}, chain_name, account_name, fileBase string, single bool) error { var file string fileBytes, err := json.MarshalIndent(toWrangle, "", " ") if err != nil { return err } if !single { file = filepath.Join(ChainsPath, chain_name, account_name, fileBase) } else { file = filepath.Join(ChainsPath, chain_name, fileBase) } log.WithField("path", file).Debug("Saving File.") err = WriteFile(string(fileBytes), file) if err != nil { return err } return 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 DeployJob(deploy *definitions.Deploy, do *definitions.Do) (result string, err error) { // Preprocess variables deploy.Source, _ = util.PreProcess(deploy.Source, do) deploy.Contract, _ = util.PreProcess(deploy.Contract, do) deploy.Instance, _ = util.PreProcess(deploy.Instance, do) deploy.Libraries, _ = util.PreProcessLibs(deploy.Libraries, do) deploy.Amount, _ = util.PreProcess(deploy.Amount, do) deploy.Nonce, _ = util.PreProcess(deploy.Nonce, do) deploy.Fee, _ = util.PreProcess(deploy.Fee, do) deploy.Gas, _ = util.PreProcess(deploy.Gas, do) // trim the extension contractName := strings.TrimSuffix(deploy.Contract, filepath.Ext(deploy.Contract)) // Use defaults deploy.Source = useDefault(deploy.Source, do.Package.Account) deploy.Instance = useDefault(deploy.Instance, contractName) deploy.Amount = useDefault(deploy.Amount, do.DefaultAmount) deploy.Fee = useDefault(deploy.Fee, do.DefaultFee) deploy.Gas = useDefault(deploy.Gas, do.DefaultGas) // assemble contract var p string if _, err := os.Stat(deploy.Contract); err == nil { p = deploy.Contract } else { p = filepath.Join(do.ContractsPath, deploy.Contract) } log.WithField("=>", p).Info("Contract path") // use the proper compiler if do.Compiler != "" { log.WithField("=>", do.Compiler).Info("Setting compiler path") } // Don't use pubKey if account override var oldKey string if deploy.Source != do.Package.Account { oldKey = do.PublicKey do.PublicKey = "" } // compile if filepath.Ext(deploy.Contract) == ".bin" { log.Info("Binary file detected. Using binary deploy sequence.") // binary deploy sequence contractCode, err := ioutil.ReadFile(p) if err != nil { result := "could not read binary file" return result, err } tx, err := deployRaw(do, deploy, contractName, string(contractCode)) if err != nil { result := "could not deploy binary contract" return result, err } result, err := deployFinalize(do, tx, deploy.Wait) if err != nil { return "", fmt.Errorf("Error finalizing contract deploy %s: %v", p, err) } return result, err } else { // normal compilation/deploy sequence resp, err := compilers.BeginCompile(do.Compiler, p, false, deploy.Libraries) if err != nil { log.Errorln("Error compiling contracts: Compilers error:") return "", err } else if resp.Error != "" { log.Errorln("Error compiling contracts: Language error:") return "", fmt.Errorf("%v", resp.Error) } // loop through objects returned from compiler switch { case len(resp.Objects) == 1: log.WithField("path", p).Info("Deploying the only contract in file") r := resp.Objects[0] if r.Bytecode != "" { result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } } case deploy.Instance == "all": log.WithField("path", p).Info("Deploying all contracts") var baseObj string for _, r := range resp.Objects { if r.Bytecode == "" { continue } result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } if strings.ToLower(r.Objectname) == strings.ToLower(strings.TrimSuffix(filepath.Base(deploy.Contract), filepath.Ext(filepath.Base(deploy.Contract)))) { baseObj = result } } if baseObj != "" { result = baseObj } default: log.WithField("contract", deploy.Instance).Info("Deploying a single contract") for _, r := range resp.Objects { if r.Bytecode == "" { continue } if strings.ToLower(r.Objectname) == strings.ToLower(deploy.Instance) { result, err = deployContract(deploy, do, r, p) if err != nil { return "", err } } } } } // Don't use pubKey if account override if deploy.Source != do.Package.Account { do.PublicKey = oldKey } return result, nil }
func Zip(do *definitions.Do) error { paths, err := filepath.Glob(filepath.Join(ChainsPath, do.Name, "*")) if err != nil { return err } for _, path := range paths { fileP := fmt.Sprintf("%s.zip", path) log.WithFields(log.Fields{ "path": path, "file": fileP, }).Debug("Making A ZipFile") dir, err := os.Open(path) if err != nil { return err } defer dir.Close() files, err := dir.Readdir(0) // grab the files list if err != nil { return err } newfile, err := os.Create(fileP) if err != nil { return err } defer newfile.Close() zipit := zip.NewWriter(newfile) defer zipit.Close() for _, fileInfo := range files { // log.WithField("file", fileInfo.Name()).Debug("Adding File Info to ZipFile") if fileInfo.IsDir() { continue } file, err := os.Open(dir.Name() + string(filepath.Separator) + fileInfo.Name()) if err != nil { return err } defer file.Close() header, err := zip.FileInfoHeader(fileInfo) if err != nil { return err } header.Method = zip.Deflate writer, err := zipit.CreateHeader(header) if err != nil { return err } _, err = io.Copy(writer, file) if err != nil { return err } } log.WithField("dir", path).Debug("Removing Directory.") if err := os.RemoveAll(path); err != nil { return err } } return nil }
func SaveAccountResults(do *definitions.Do) error { addrFile, err := os.Create(filepath.Join(ChainsPath, do.Name, "addresses.csv")) if err != nil { return fmt.Errorf("Error creating addresses file. This usually means that there was a problem with the chain making process.") } defer addrFile.Close() log.WithField("name", do.Name).Debug("Creating file") actFile, err := os.Create(filepath.Join(ChainsPath, do.Name, "accounts.csv")) if err != nil { return fmt.Errorf("Error creating accounts file.") } log.WithField("path", filepath.Join(ChainsPath, do.Name, "accounts.csv")).Debug("File successfully created") defer actFile.Close() log.WithField("name", do.Name).Debug("Creating file") actJSONFile, err := os.Create(filepath.Join(ChainsPath, do.Name, "accounts.json")) if err != nil { return fmt.Errorf("Error creating accounts file.") } log.WithField("path", filepath.Join(ChainsPath, do.Name, "accounts.json")).Debug("File successfully created") defer actJSONFile.Close() valFile, err := os.Create(filepath.Join(ChainsPath, do.Name, "validators.csv")) if err != nil { return fmt.Errorf("Error creating validators file.") } defer valFile.Close() accountJsons := make(map[string]*accountInfo) for _, account := range do.Accounts { accountJsons[account.Name] = &accountInfo{ Address: account.Address, PubKey: account.PubKey, PrivKey: account.MintKey.PrivKey[1].(string), } _, err := addrFile.WriteString(fmt.Sprintf("%s,%s\n", account.Address, account.Name)) if err != nil { log.Error("Error writing addresses file.") return err } _, err = actFile.WriteString(fmt.Sprintf("%s,%d,%s,%d,%d\n", account.PubKey, account.Tokens, account.Name, account.MintPermissions.MintBase.MintPerms, account.MintPermissions.MintBase.MintSetBit)) if err != nil { log.Error("Error writing accounts file.") return err } if account.Validator { _, err = valFile.WriteString(fmt.Sprintf("%s,%d,%s,%d,%d\n", account.PubKey, account.ToBond, account.Name, account.MintPermissions.MintBase.MintPerms, account.MintPermissions.MintBase.MintSetBit)) if err != nil { log.Error("Error writing validators file.") return err } } } addrFile.Sync() actFile.Sync() valFile.Sync() j, err := json.MarshalIndent(accountJsons, "", " ") if err != nil { return err } _, err = actJSONFile.Write(j) if err != nil { return err } log.WithField("path", actJSONFile.Name()).Debug("Saving File.") log.WithField("path", addrFile.Name()).Debug("Saving File.") log.WithField("path", actFile.Name()).Debug("Saving File.") log.WithField("path", valFile.Name()).Debug("Saving File.") return 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 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 PreProcess(toProcess string, do *definitions.Do) (string, error) { // $block.... $account.... etc. should be caught. hell$$o should not // :$libAddr needs to be caught catchEr := regexp.MustCompile("(^|\\s|:)\\$([a-zA-Z0-9_.]+)") // If there's a match then run through the replacement process if catchEr.MatchString(toProcess) { log.WithField("match", toProcess).Debug("Replacement Match Found") // find what we need to catch. processedString := toProcess for _, jobMatch := range catchEr.FindAllStringSubmatch(toProcess, -1) { jobName := jobMatch[2] varName := "$" + jobName var innerVarName string var wantsInnerValues bool = false /* log.WithFields(log.Fields{ "var": varName, "job": jobName, }).Debugf("Correcting match %d", i+1) */ // first parse the reserved words. if strings.Contains(jobName, "block") { block, err := replaceBlockVariable(toProcess, do) if err != nil { log.WithField("err", err).Error("Error replacing block variable.") return "", err } /*log.WithFields(log.Fields{ "var": toProcess, "res": block, }).Debug("Fixing Variables =>")*/ processedString = strings.Replace(processedString, toProcess, block, 1) } if strings.Contains(jobName, ".") { //for functions with multiple returns wantsInnerValues = true var splitStr = strings.Split(jobName, ".") jobName = splitStr[0] innerVarName = splitStr[1] } // second we loop through the jobNames to do a result replace for _, job := range do.Package.Jobs { if string(jobName) == job.JobName { if wantsInnerValues { for _, innerVal := range job.JobVars { if innerVal.Name == innerVarName { //find the value we want from the bunch processedString = strings.Replace(processedString, varName, innerVal.Value, 1) log.WithFields(log.Fields{ "job": string(jobName), "varName": innerVarName, "result": innerVal.Value, }).Debug("Fixing Inner Vars =>") } } } else { log.WithFields(log.Fields{ "var": string(jobName), "res": job.JobResult, }).Debug("Fixing Variables =>") processedString = strings.Replace(processedString, varName, job.JobResult, 1) } } } } return processedString, nil } // if no matches, return original return toProcess, nil }