ããã«ã¡ã¯
ã€ãŒãµãªã¢ã ã®ã¹ããŒãå¥çŽã®æåãã¹ãã®ããã«ãã§ããã°ã·ã³ãã«ãªãœãªã¥ãŒã·ã§ã³ãéçºãããšããã¢ã€ãã¢ããããŸããã Remixã®[å®è¡]ã¿ãã®æ©èœã«äŒŒãæäœãè¡ãããšã¯è峿·±ããã®ã«ãªããŸããã
ã¢ããªã±ãŒã·ã§ã³ã§ã§ããããšïŒ
Golangã®ã·ã³ãã«ãªããã¯ãšã³ãã§ããããšã倿ããŸããã
- ãšã³ããã€ã³ãã§éçãªHTMLããŒãžãçæãããã©ãŠã¶ãŒã«éä¿¡ããŸãã
- toml configããèšå®ãååŸããŸãã
- RPCçµç±ã§ã€ãŒãµãªã¢ã ããŒãã«æ¥ç¶ããŸãã
- ã€ãŒãµãªã¢ã ã·ãã¥ã¬ãŒã¿ãŒã«ãªããŸãã
- .solãã¡ã€ã«ãã³ã³ãã€ã«ããŸãã
- å¥çŽãå±éããŸãã
- å¥çŽã«æžã蟌ã¿ãå¥çŽããæ
å ±ãèªã¿åããŸãã
- ã€ãŒãµãªã¢ã ã¢ãã¬ã¹ãžã®ETH転éãè¡ããŸãã
- Ethereumãããã¯ãŒã¯ã«é¢ããæ
å ±ãæåŸã®ãããã¯ããã®æ
å ±ãåä¿¡ããŸãã
- äœæ¥çšã«1ã€ã®ãã£ã¬ã¯ããªããè€æ°ã®ã³ã³ãã©ã¯ããããŒãããŠãããäœæ¥ããç¹å®ã®ã³ã³ãã©ã¯ããéžæã§ããŸãã
- æå·åãããŠããªãæ
å ±ãã¯ãããŒã«ä¿åããŸãã
- 15åããšã«ç§å¯éµãèŠæ±ãããã®ãŠãŒã¶ãŒã«ä»£ãã£ãŠæäœãå®è¡ãããŸãã
- çŸåšã®ã»ãã·ã§ã³ã«é¢ããæ
å ±ã衚瀺ããŸããçŸåšã®ã¢ãã¬ã¹ãçŸåšã®æ®é«ãéžæããsolãã¡ã€ã«ããã®äžã®å¥çŽã
- ãã¹ãŠã®ã³ã³ãã©ã¯ãã¡ãœããã®ããŒãã«ãäœæããŸãã
é çªã«ïŒ
Golangãéžæããã®ã¯ã ã²ã¹ãæ§ç¯ãããŠããgoethereumã³ãŒãããŒã¹ãæ¬åœã«å¥œãã ã£ãããã§ãã
éçãªHTMLãçæããã«ã¯ãæšæºã®Golangããã±ãŒãžãhtml /ãã³ãã¬ãŒããã䜿çšãããŸãã ããã§ã¯äœããã€ã³ãããŸããããã¹ãŠã®ãã³ãã¬ãŒãã¯ãããžã§ã¯ããã³ãã¬ãŒãããã±ãŒãžã«ãããŸãã
äžèšã§æžããããã«ãã€ãŒãµãªã¢ã ã䜿çšããã«ã¯ãgo-ethereumã³ãŒãããŒã¹ããŒãžã§ã³1.7.3ãéžæããŸããã
go-ethereumã®ã¢ãã€ã«ããã±ãŒãžã䜿çšãããã£ãã®ã§ãããã¢ãã€ã«ã¯ãã°ããæŽæ°ãããŠããããçŸåšã®Abi圢åŒã§ã¯æ£ããåäœããŸããã ããŒã¿ãåŠçãããšãã«ãåæ§ã®ãšã©ãŒã衚瀺ãããŸãã
abi: cannot unmarshal *big.Int in to []interface {}
ãã®ãšã©ãŒã¯ãã§ã«ä¿®æ£ãããŠããŸãããã¡ã€ã³ãã©ã³ãã§ã¯ããããæžããæç¹ã§ã®ä¿®æ£ã¯ãŸã 远å ãããŠããŸããã
ããã«ãããããããç§ã¯å¥ã®ãœãªã¥ãŒã·ã§ã³ãã©ãããŒã¬ã¹ãéžæããŸããã ã¢ãã€ã«ããã±ãŒãžã®é¢æ°ã¯ãåºæ¬çã«äž»ãªæ©èœã®äŸ¿å©ãªã©ãããŒã§ãã
ãã®çµæãgo-ethereumããabiïŒ+ abiã«äŸåããè€æ°ã®ããã±ãŒãžïŒãæäœããããã®ããã±ãŒãžããããžã§ã¯ãã«åã蟌ã¿ããã«ãªã¯ãšã¹ãããã³ãŒãã远å ããŸããã
ã¹ããŒãã³ã³ãã©ã¯ãã䜿çšããå¿
èŠããããããsolãã¡ã€ã«ããç¹å®ã®ã³ã³ãã©ã¯ããæäœããããã®goããã±ãŒãžãçæã§ããabigenãŠãŒãã£ãªãã£ã¯ãç§ã«ã¯äžåãã§ããã
æ§é ãšããã®æ§é ãã¬ã·ãŒããŒã§ããã¡ãœãããäœæããŸããïŒGolangã®çšèªã«ééãããªãå ŽåïŒïŒ
type EthWorker struct { Container string
å®å
šãªã€ã³ã¿ãŒãã§ãŒã¹ã¯æ¬¡ã®ããã«ãªããŸãã
type ReadWriterEth interface { Transact() (string, error)
å¥çŽã«æ
å ±ãæžã蟌ãããã®é¢æ°ïŒ
ååŒ func (w *EthWorker) Transact() (string, error) {
å¥çŽããæ
å ±ãèªã¿åãããã®æ©èœïŒ
é»è©±ãã func (w *EthWorker) Call() (string, error) { inputs, err := w.ParseInput() if err != nil { return "", errors.Wrap(err, "parse input") } key, _ := crypto.GenerateKey() auth := bind.NewKeyedTransactor(key) contract := bind.NewBoundContract( common.HexToAddress(w.ContractAddress), Containers.Containers[w.Container].Contracts[w.Contract].Abi, Client, Client, ) opt := &bind.CallOpts{ Pending: true, From: auth.From, } outputs := Containers.Containers[w.Container].Contracts[w.Contract].OutputsInterfaces[w.Endpoint] if err := contract.Call( opt, &outputs, w.Endpoint, inputs..., ); err != nil { return "", errors.Wrap(err, "call contract") } result, err := w.ParseOutput(outputs) if err != nil { return "", errors.Wrap(err, "parse output") } return result, err }
å¥çŽãå±éããããã®æ©èœïŒ
å±éãã func (w *EthWorker) Deploy() (string, string, error) { inputs, err := w.ParseInput() if err != nil { return "", "", errors.Wrap(err, "parse input") } pk := strings.TrimPrefix(w.Key, "0x") key, err := crypto.HexToECDSA(pk) if err != nil { return "", "", errors.Wrap(err, "hex to ECDSA") } auth := bind.NewKeyedTransactor(key) current_bytecode := Containers.Containers[w.Container].Contracts[w.Contract].Bin current_abi := Containers.Containers[w.Container].Contracts[w.Contract].Abi addr, tr, _, err := bind.DeployContract(auth, current_abi, common.FromHex(current_bytecode), Client, inputs...) if err != nil { log.Printf("error %s", err.Error()) return "", "", errors.Wrap(err, "deploy contract") } var receipt *types.Receipt switch v := Client.(type) { case *backends.SimulatedBackend: v.Commit() receipt, err = v.TransactionReceipt(context.Background(), tr.Hash()) if err != nil { return "", "", errors.Wrap(err, "transaction receipt") } case *ethclient.Client: receipt, err = bind.WaitMined(context.Background(), v, tr) if err != nil { return "", "", errors.Wrap(err, "transaction receipt") } } if err != nil { return "", "", errors.Errorf("error transact %s: %s", tr.Hash().String(), err.Error(), ) } responce := fmt.Sprintf(templates.DeployResult, tr.Nonce(), auth.From.String(), addr.String(), tr.GasPrice().String(), receipt.GasUsed.String(), new(big.Int).Mul(receipt.GasUsed, tr.GasPrice()).String(), receipt.Status, receipt.TxHash.String(), ) return responce, addr.String(), nil }
ãŠãŒã¶ãŒãWebããŒãžã®ãã©ãŒã ã«å
¥åããããŒã¿ããCall and Transactæ©èœã«è»¢éã§ããããŒã¿ãååŸããæ¹æ³ã®åé¡ã解決ããå¿
èŠããããŸããã
å¥çŽã®abiã¡ãœããããç¹å®ã®ãã£ãŒã«ãã«å¿
èŠãªããŒã¿åãåŠç¿ãããŠãŒã¶ãŒãWebããŒãžã®ãã©ãŒã ã«å
¥åãããã®ãããããããšã»ã©è¯ããã®ã¯æãã€ããŸããã§ããã ããªãã¡ ããŒã¿åãå¿ããå Žåããã®ãœãªã¥ãŒã·ã§ã³ã¯ãã®ããŒã¿åã§ã¯æ©èœããŸããã ã³ãŒãã倿Žããå¿
èŠããããŸãã ParseInput颿°ã«å®è£
ãããŸã
è§£æå
¥å func (w *EthWorker) ParseInput() ([]interface{}, error) {
ParseOutput颿°ã§ã€ãŒãµãªã¢ã ããååŸããããŒã¿ã«å¯ŸããŠåæ§ã®å€æãè¡ããŸãã
è§£æåºå func (w *EthWorker) ParseOutput(outputs []interface{}) (string, error) { if len(Containers.Containers[w.Container].Contracts[w.Contract].Abi.Methods[w.Endpoint].Outputs) == 0 { return "", nil } if Containers.Containers[w.Container] == nil || Containers.Containers[w.Container].Contracts[w.Contract] == nil { return "", errors.New("input values incorrect") } if len(Containers.Containers[w.Container].Contracts[w.Contract].Abi.Methods[w.Endpoint].Outputs) != 0 && Containers.Containers[w.Container].Contracts[w.Contract].OutputsInterfaces[w.Endpoint] == nil { return "", errors.New("input values incorrect") } output_args := Containers.Containers[w.Container].Contracts[w.Contract].Abi.Methods[w.Endpoint].Outputs if len(outputs) != len(output_args) { return "", errors.New("incorrect inputs") } var item_array []string for i := 0; i < len(outputs); i++ { switch output_args[i].Type.Type.String() { case "bool": item := strconv.FormatBool(*outputs[i].(*bool)) item_array = append(item_array, item) case "[]bool": boolArray := *outputs[i].(*[]bool) var boolItems []string for _, bool_value := range boolArray { item := strconv.FormatBool(bool_value) boolItems = append(boolItems, item) } item := "[ " + strings.Join(boolItems, ",") + " ]" item_array = append(item_array, item) case "string": item_array = append(item_array, *outputs[i].(*string)) case "[]string": array := *outputs[i].(*[]string) var items []string for _, value := range array { items = append(items, value) } item := "[ " + strings.Join(items, ",") + " ]" item_array = append(item_array, item) case "[]byte": array := *outputs[i].(*[]byte) var items []string for _, value := range array { items = append(items, string(value)) } item := "[ " + strings.Join(items, ",") + " ]" item_array = append(item_array, item) case "[][]byte": array := *outputs[i].(*[][]byte) var items string for _, array2 := range array { var items2 []string for _, value := range array2 { items2 = append(items2, string(value)) } item2 := "[ " + strings.Join(items2, ",") + " ]" items = items + "," + item2 } item_array = append(item_array, items) case "common.Address": item := *outputs[i].(*common.Address) item_array = append(item_array, item.String()) case "[]common.Address": addrArray := *outputs[i].(*[]common.Address) var addrItems []string for _, value := range addrArray { addrItems = append(addrItems, value.String()) } item := "[ " + strings.Join(addrItems, ",") + " ]" item_array = append(item_array, item) case "common.Hash": item := *outputs[i].(*common.Hash) item_array = append(item_array, item.String()) case "[]common.Hash": hashArray := *outputs[i].(*[]common.Hash) var hashItems []string for _, value := range hashArray { hashItems = append(hashItems, value.String()) } item := "[ " + strings.Join(hashItems, ",") + " ]" item_array = append(item_array, item) case "int8": item := *outputs[i].(*int8) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "int16": item := *outputs[i].(*int16) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "int32": item := *outputs[i].(*int32) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "int64": item := *outputs[i].(*int64) str := strconv.FormatInt(item, 10) item_array = append(item_array, str) case "uint8": item := *outputs[i].(*uint8) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "uint16": item := *outputs[i].(*uint16) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "uint32": item := *outputs[i].(*uint32) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "uint64": item := *outputs[i].(*uint64) str := strconv.FormatInt(int64(item), 10) item_array = append(item_array, str) case "*big.Int": item := *outputs[i].(**big.Int) item_array = append(item_array, item.String()) case "[]*big.Int": bigArray := *outputs[i].(*[]*big.Int) var items []string for _, v := range bigArray { items = append(items, v.String()) } item := "[ " + strings.Join(items, ",") + " ]" item_array = append(item_array, item) } } return strings.Join(item_array, " , "), nil }
åè¿°ã®abigenãŠãŒãã£ãªãã£ã®ã³ãŒãããŒã¹ãããSolidityã³ã³ãã€ã©ãæäœããããã®æ©èœãåŒãè£ããŸããã æçµçã«ãç§ã¯ã»ãŒãã¹ãŠã®å¥çŽã§abiãšãã€ãã³ãŒããååŸããŸããã Bind颿°ã«å®è£
ãããŠããŸãã
ãã€ã³ã func Bind(dirname, solcfile string) (*ContractContainers, error) { result := &ContractContainers{ Containers: make(map[string]*ContractContainer), } allfiles, err := ioutil.ReadDir(dirname) if err != nil { return nil, errors.Wrap(err, "error ioutil.ReadDir") } for _, v := range allfiles { if v.IsDir() { continue } if hasSuffixCaseInsensitive(v.Name(), ".sol") { contracts, err := compiler.CompileSolidity(solcfile, dirname+string(os.PathSeparator)+v.Name()) if err != nil { return nil, errors.Wrap(err, "CompileSolidity") } c := &ContractContainer{ ContainerName: v.Name(), Contracts: make(map[string]*Contract), } for name, contract := range contracts { a, _ := json.Marshal(contract.Info.AbiDefinition) ab, err := abi.JSON(strings.NewReader(string(a))) if err != nil { return nil, errors.Wrap(err, "abi.JSON") } nameParts := strings.Split(name, ":") var ab_keys []string ouputs_map := make(map[string][]interface{}) inputs_map := make(map[string][]interface{}) for key, method := range ab.Methods { ab_keys = append(ab_keys, key) var o []interface{} var i []interface{} for _, v := range method.Outputs { var ar interface{} switch v.Type.Type.String() { case "bool": ar = new(bool) case "[]bool": ar = new([]bool) case "string": ar = new(string) case "[]string": ar = new([]string) case "[]byte": ar = new([]byte) case "[][]byte": ar = new([][]byte) case "common.Address": ar = new(common.Address) case "[]common.Address": ar = new([]common.Address) case "common.Hash": ar = new(common.Hash) case "[]common.Hash": ar = new([]common.Hash) case "int8": ar = new(int8) case "int16": ar = new(int16) case "int32": ar = new(int32) case "int64": ar = new(int64) case "uint8": ar = new(uint8) case "uint16": ar = new(uint16) case "uint32": ar = new(uint32) case "uint64": ar = new(uint64) case "*big.Int": ar = new(*big.Int) case "[]*big.Int": ar = new([]*big.Int) default: return nil, errors.Errorf("unsupported type: %s", v.Type.Type.String()) } o = append(o, ar) } ouputs_map[method.Name] = o for _, v := range method.Inputs { var ar interface{} switch v.Type.Type.String() { case "bool": ar = new(bool) case "[]bool": ar = new([]bool) case "string": ar = new(string) case "[]string": ar = new([]string) case "[]byte": ar = new([]byte) case "[][]byte": ar = new([][]byte) case "common.Address": ar = new(common.Address) case "[]common.Address": ar = new([]common.Address) case "common.Hash": ar = new(common.Hash) case "[]common.Hash": ar = new([]common.Hash) case "int8": ar = new(int8) case "int16": ar = new(int16) case "int32": ar = new(int32) case "int64": ar = new(int64) case "uint8": ar = new(uint8) case "uint16": ar = new(uint16) case "uint32": ar = new(uint32) case "uint64": ar = new(uint64) case "*big.Int": ar = new(*big.Int) case "[]*big.Int": ar = new([]*big.Int) default: return nil, errors.Errorf("unsupported type: %s", v.Type.Type.String()) } i = append(i, ar) } inputs_map[method.Name] = i } sort.Strings(ab_keys) con := &Contract{ Name: nameParts[len(nameParts)-1], Abi: ab, AbiJson: string(a), Bin: contract.Code, SortKeys: ab_keys, OutputsInterfaces: ouputs_map, InputsInterfaces: inputs_map, } c.ContractNames = append(c.ContractNames, nameParts[len(nameParts)-1]) c.Contracts[nameParts[len(nameParts)-1]] = con } sort.Strings(c.ContractNames) result.ContainerNames = append(result.ContainerNames, c.ContainerName) result.Containers[c.ContainerName] = c } } sort.Strings(result.ContainerNames) return result, err }
ãã®é¢æ°ã¯ãã¢ãã€ã«ããã±ãŒãžã§ã®å®éšãã倧ããªã³ãŒããããã¯ãæ®ããŸãããããŸã åé€ããŠããŸããããåã«ãªãã¡ã¯ã¿ãªã³ã°ããŸããã
ããªã倧ããªContractContainersæ§é ãäœæããããã«çŸåšã®å¥çŽã«é¢ãããã¹ãŠã®æ
å ±ãé
眮ããŸãããå°æ¥ãã¢ããªã±ãŒã·ã§ã³ã¯ãããããã¹ãŠã®æ
å ±ãååŸããŸãã
æåŸã«ããã®ä»çµã¿ã説æããŸãã
Linuxã§ã®ã¿ããã°ã©ã ãå®è¡ããŸããã è¿ãã«ä»ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ãããŸããã
Windowsããã³Macçšã®å®è¡å¯èœãã¡ã€ã«ãã³ã³ãã€ã«ããŸãããã
ãŸãããã©ãããã©ãŒã çšã®Solidityã³ã³ãã€ã©ãå¿
èŠã§ãã ãããããããæãé£ããç¹ã§ãã
ããã§ã³ã³ãã€ã«æžã¿ã®ãã€ããªãŸãã¯ãœãŒã¹ãååŸãããã ããã§è©³çްã確èªã§ããŸã ã Linuxããã³Windowsçšã®ããŒãžã§ã³0.4.18ããã³0.4.19ãããžã§ã¯ãã®solcãã£ã¬ã¯ããªã«é
眮ããŸããã ã·ã¹ãã ã«ãã§ã«ã€ã³ã¹ããŒã«ãããŠããã³ã³ãã€ã©ã䜿çšããããšãã§ããŸãã ã·ã¹ãã ã«Solidityã³ã³ãã€ã©ããããã©ããã確èªããã«ã¯ãã³ãã³ãããã³ããã§æ¬¡ã®ããã«å
¥åããŸãã
solc âversion
çããããã§ããå ŽåïŒ
solc, the solidity compiler commandline interface Version: 0.4.18+commit.9cf6e910.Linux.g++
ãã®åŸããã¹ãŠãé 調ã§ãã
ããã€ãã®ã©ã€ãã©ãªãå¿
èŠã«ãªãå Žåã¯ãUbuntuããããèŠæ±ããå Žåãªã©ã«ãããããã€ã³ã¹ããŒã«ããã ãã§ãã
./solc: error while loading shared libraries: libz3.so.4: cannot open shared object file: No such file or directory
ãæ¬¡ã«libz3-devãé
眮ããŸã
次ã«ãã€ãŒãµãªã¢ã ã䜿çšããã¢ãŒããæ±ºå®ããå¿
èŠããããŸãã 2ã€ã®æ¹æ³ããããŸãã
- RPCãä»ããŠã€ãŒãµãªã¢ã ããŒãã«æ¥ç¶ããããŒããåæãããŠãããããã¯ãŒã¯ã§äœæ¥ããŸãã ããã¯ããã©ã€ããŒãã€ãŒãµãªã¢ã ãããã¯ãŒã¯ãããå ŽåããŸãã¯æ¢ã«åæããŒããããå Žåã«äŸ¿å©ã§ãã
- ã€ãŒãµãªã¢ã ãããã¯ãã§ãŒã³ãšãã¥ã¬ãŒã¿ãŒã ãšãã¥ã¬ãŒã¿ãŒã¢ãŒãã§äœæ¥ããå Žåã¯ãUTC JSONãã¡ã€ã«ãããŒã¹ãã¢ãã¡ã€ã«åœ¢åŒã§ããŒã¹ãã¢ãã£ã¬ã¯ããªã«é
眮ããå¿
èŠããããŸãããããã®ãã¡ã€ã«ã埩å·åããããã®ãã¹ã¯ãŒãã¯ç©ºã«ãªããŸãã
確ãã«ãã£ãšçŸããããããšã¯ã§ããŸãããäŸãšããŠã¯ãæ¢åã®ãœãªã¥ãŒã·ã§ã³ãéåžžã«é©ããŠããŸãã ãããã®ãã¡ã€ã«ãããã¢ããªã±ãŒã·ã§ã³ã¯ã€ãŒãµãªã¢ã ã¢ãã¬ã¹ãååŸãããŒã以å€ã®ãã©ã³ã¹ãåããŸãã
äŸãšããŠãããŒã¹ãã¢ãã£ã¬ã¯ããªã«5ã€ã®ãã¡ã€ã«ãé
眮ããŸãã ãããã¯ãã¹ãç°å¢ã§äœ¿çšã§ããŸãã
config.yaml configãå
¥åããŸãã
- connect_url-rpcãµãŒããŒã€ãŒãµãªã¢ã ããŒãã«æ¥ç¶ããããã®URLã ãã®ãã£ãŒã«ãã空çœã®ãŸãŸã«ãããšãã¢ããªã±ãŒã·ã§ã³ã¯ã€ãŒãµãªã¢ã ãšãã¥ã¬ãŒã·ã§ã³ã¢ãŒãã§èµ·åããŸããããã¯äžèšã§èª¬æãããšããã§ãã
- sol_pathã¯ãã¢ããªã±ãŒã·ã§ã³ãæ€çŽ¢ããã¹ããŒãã³ã³ãã©ã¯ããå«ããã©ã«ããŒã§ãã ã¢ããªã±ãŒã·ã§ã³ã¯ãã«ãŒããã£ã¬ã¯ããªã«ãã.solãã¡ã€ã«ãæ¢ããŸãã ãµããã£ã¬ã¯ããªã¯ç¡èŠãããŸãã ãã ããäœæ¥ããå¥çŽããµããã£ã¬ã¯ããªå
ã®å¥çŽãåç
§ããŠããå Žåã¯ã倧äžå€«ã§ããæäžäœã®å¥çŽãéããŠè¿œå ãããŸãã
- keystore_path-UTC JSONãã¡ã€ã«ãå«ããã£ã¬ã¯ããªããŒã¹ãã¢ãã¡ã€ã«ã 埩å·åã®ããã®ãã¹ã¯ãŒãã¯ç©ºã§ãªããã°ãªããªãããšãæãåºãããŠãã ããã
- gaslimit-ãã©ã³ã¶ã¯ã·ã§ã³ãŸãã¯å¥çŽã®å±éã®ã¬ã¹å¶éã
- port-ããŒã«ã«httpãµãŒããŒã®ããŒãã
- solc-Solidityã³ã³ãã€ã©ãžã®ãã¹;空ã®ãŸãŸã«ãããšãã¢ããªã±ãŒã·ã§ã³ã¯ã·ã¹ãã ã«ã€ã³ã¹ããŒã«ãããã³ã³ãã€ã©ã䜿çšããŸãã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åããŸãã æ§æãã¡ã€ã«ã®ãããã£ã¬ã¯ããªãžã®ãã¹ã¯ã-configãã©ã°ãä»ããŠæå®ã§ããŸã
./efront-v0.0.1-linux-amd64 -config $GOPATH/src/ethereum-front/
ãã©ãŠã¶ã®ãªã³ã¯ããã©ããŸããããã©ã«ãã§ã¯httpïŒ// localhostïŒ8085ã§ãã
ç§å¯éµãå
¥åããå¿
èŠããããŸãã 5ã€ã®ãã¹ãã¢ãã¬ã¹ã®ç§å¯ããŒã¯ãkeys.txtã«ãããŸãã ãã®ç§å¯ããŒã¯ããã©ãŠã¶ã®Cookieã«15åéä¿åãããŸãã æ¬¡ã¯æ°ãããªã¯ãšã¹ãã§ãã çŸåšãäœãæå·åãããŠããŸããã

éžæããŠãã³ã³ããïŒ.solãã¡ã€ã«ïŒããã³ã¢ããªã±ãŒã·ã§ã³ããã®äžã«èŠã€ããã³ã³ãã©ã¯ããéžæããŸãã

ããã«ã察å¿ãããã§ãã¯ããã¯ã¹ããªã³ã«ããŠãäžåºŠå±éããå¥çŽã®ã¢ãã¬ã¹ãå
¥åããããæ°ããå¥çŽãå±éã§ããŸãã [å±é]ãã§ãã¯ããã¯ã¹ããªã³ã®å Žåãã¢ãã¬ã¹ãã£ãŒã«ãã¯ç¡èŠãããŸãã
ãã¹ãŠãããŸããã£ãå Žåããã©ãŠã¶ã«åæ§ã®ç»åã衚瀺ãããŸãã

ãšã©ãŒãããå Žåããããã¯ã€ã³ã¿ãŒãã§ãŒã¹ã®äžéšã®ããã¹ããšãªã¢ã«è¡šç€ºãããŸãã
ããŒãžã®äžéšã«ã¯ã2ã€ã®ãã°ã€ã³ãªã³ã¯ãšã¢ããããŒããªã³ã¯ããããŸãã
ãã°ã€ã³ããªãã€ã¬ã¯ããããæ°ããç§å¯éµãå
¥åãããŸãã éžæããå¥çŽãžã®ãªãã€ã¬ã¯ããã¢ããããŒãããŸãã
以äžã¯ãçŸåšã®ã»ãã·ã§ã³ã«é¢ããæ
å ±ã§ãã

- ã¢ãã¬ã¹ïŒ-çŸåšã®ç§å¯éµã«äžèŽããã€ãŒãµãªã¢ã ã¢ãã¬ã¹
- balance-çŸåšã®ãããã¯ãŒã¯ã®ãã®ã¢ãã¬ã¹ã§ã®Ethæ®é«ã ããŒãžãæŽæ°ããããã³ã«èŠæ±ãããŸã
- ãã¡ã€ã«ãšå¥çŽã¯ããããéžæãããsolãã¡ã€ã«ãšãã®äžã®å¥çŽã§ãã ã¯ãããŒã«ä¿åãããããããååŸ
- å¥çŽã¢ãã¬ã¹ã¯ãçŸåšã®ãããã¯ãŒã¯ã«å±éãããå¥çŽã®ã¢ãã¬ã¹ã§ãã ã¯ãããŒã«ä¿åãããããããååŸ
次ã¯2ã€ã®ããŒãã«ã§ãã
çŸåšã®ã³ã³ãã©ã¯ãã®ã¡ãœãããæäœããããã®å·Šã®è¡šã éžæããå¥çŽã«å¿ããŠãåçã«å€åããŸãã
å³ã®è¡šã¯ãã€ãŒãµãªã¢ã ãæäœããããã®äžè¬çãªæ©èœã§ãã
- ãã©ã³ã¹-çŸåšã®ãããã¯ãŒã¯ã§éžæããã€ãŒãµãªã¢ã ã¢ãã¬ã¹ã®ãã©ã³ã¹ã確èªããŸãã
- ã¬ã¹äŸ¡æ Œ-iã®çŸåšã®ã¬ã¹äŸ¡æ Œã
- æåŸã®ãããã¯-çŸåšã®ãããã¯ã®çªå·ã ã·ãã¥ã¬ãŒã¿ãŒã§ã¯æ©èœããŸããã
- ã€ãŒãµãªã¢ã ãããã¯ãŒã¯ã®ã¬ã¹å¶é-æåŸã®ãããã¯ã®ã¬ã¹å¶éã ã·ãã¥ã¬ãŒã¿ãŒã§ã¯æ©èœããŸããã
- ã€ãŒãµãªã¢ã ãããã¯ãŒã¯æé-æåŸã®ãããã¯ã®ãã€ãã³ã°æéã ã·ãã¥ã¬ãŒã¿ãŒã§ã¯æ©èœããŸããã
- ã€ãŒãµãªã¢ã ãããã¯ãŒã¯ã®é£æåºŠ-æåŸã®ãããã¯ã®è€éãã ã·ãã¥ã¬ãŒã¿ãŒã§ã¯æ©èœããŸããã
- 転é-誰ã«ãã©ã®ãããã®ã¯ã€ã転éãããã
- æéã®èª¿æŽ-ã·ãã¥ã¬ãŒã¿ãŒã®æé管çã æ£æ°ãå
¥åããå¿
èŠããããŸãã ãããŠãã»ãã®æ°ç§éãã·ãã¥ã¬ãŒã¿ãŒã®æéãé·ããªããŸãã
泚ïŒãã©ã³ã¶ã¯ã·ã§ã³ïŒãããã¯ãã§ãŒã³ãžã®æžãèŸŒã¿æäœïŒãå®è¡ãããšããããŒãžãããŒãããããŸã§åŸ
æ©ããŸããããã«ã¯æ°ç§ãããå ŽåããããŸãã .
, textarea ( ):

- Nonce â
- From â
- Contract Address â
- Gas price â Gas
- Gas Used â Gas
- Cost/Fee: Wai
- Status â 1, , 0, .
- Transaction Hash â
.
C OS. bin.
:
- html 5.
- front Ethereum, ether,
- , -
ãœãŒã¹ã³ãŒã
ã©ããããããšãã