ããã¯ãå®éã«ã¯ãã¹ãŠã¹ããŒãã³ã³ãã©ã¯ãã«é¢ãããã®ã§ãã
ããããã¹ããŒãã³ã³ãã©ã¯ããäœã§ãããããŸã£ããæ³åããŠããããäžè¬çã«æå·åãšã¯çšé ãå Žåã¯ãããŒã¿ããŒã¹å
ã®ã¹ãã¢ãããã·ãŒãžã£ãšã¯äœããå®å
šã«æ³åã§ããŸãã ãŠãŒã¶ãŒã¯ããµãŒããŒäžã§åäœããã³ãŒããäœæããŸãã ãŠãŒã¶ãŒãããããäœæããŠå
¬éãããšäŸ¿å©ã§ãããããããå®è¡ããŠãå®å
šã§ãã
æ®å¿µãªãããã»ãã¥ãªãã£ã¯ãŸã éçºãããŠããªããããããã§ã¯èª¬æããŸããããããã€ãã®ãã³ãã瀺ããŸãã
ãŸããGoã«ã€ããŠãèšè¿°ããŸããããã®ã©ã³ã¿ã€ã ã«ã¯ããã€ãã®éåžžã«å
·äœçãªå¶éããããŸãããæãéèŠãªã®ã¯ãæŠããŠãå€åºäžã§ãªãå¥ã®ãããžã§ã¯ãã«ãªã³ã¯ã§ããªãããšã§ããããã«ããããµãŒãããŒãã£ã®ã³ãŒããå®è¡ãããã³ã«ã©ã³ã¿ã€ã ãåæ¢ããŸãã äžè¬ã«ãããçš®ã®ã€ã³ã¿ãŒããªã¿ãŒã䜿çšãããªãã·ã§ã³ããããŸããããã«å¯ŸããŠãå®å
šã«å¥å
šãªLuaãšå®å
šã«å¥å
šãªWASMãèŠã€ãããŸããããäœããã®çç±ã§Luaã«ã¯ã©ã€ã¢ã³ããè¿œå ããããããŸããã ãæ¯ææŽæ°ããããããä»æ§ã確å®ãããŸã§åŸ
æ©ããŸãã 2çªç®ã®ãšã³ãžã³ãšããŠäœ¿çšããŸãã
圌èªèº«ã®è¯å¿ãšã®é·ãæŠãã®çµæãGOã§ã¹ããŒãã³ã³ãã©ã¯ããäœæããããšã決å®ãããŸããã å®éãã³ã³ãã€ã«ãããGOã³ãŒããå®è¡ããããã®ã¢ãŒããã¯ãã£ãæ§ç¯ããå Žåãã»ãã¥ãªãã£ã®ããã«ãã®å®è¡ãå¥ã®ããã»ã¹ã«è»¢éããå¿
èŠããããå¥ã®ããã»ã¹ã«è»¢éãããšIPCã®ããã©ãŒãã³ã¹ãäœäžããŸãããåŸã§å®è¡å¯èœãã¡ã€ã«ã®ããªã¥ãŒã ãç解ãããšãã«ã³ãŒãããã®ãœãªã¥ãŒã·ã§ã³ãéžãã ã®ã¯ãªããšãªã楜ããããšã§ããã åé¡ã¯ãåã
ã®ã³ãŒã«ã«é
延ãè¿œå ããããã®ã®ãã¹ã±ãŒã©ãã«ã§ããããšã§ãã å€ãã®ãªã¢ãŒãã©ã³ã¿ã€ã ãäžããããšãã§ããŸãã
ãããæ確ã«ãªãããã«ãªããã決å®ã«ã€ããŠããå°ãã åã¹ããŒãã³ã³ãã©ã¯ãã¯2ã€ã®éšåã§æ§æããã1ã€ã®éšåã¯ã¯ã©ã¹ã³ãŒãã§ã2çªç®ã®éšåã¯ãªããžã§ã¯ãããŒã¿ã§ãããããã£ãŠãåãã³ãŒãäžã§ãã³ãŒããå
¬éããããåºæ¬çã«åãåäœãããå€ãã®ã³ã³ãã©ã¯ããäœæã§ããŸãããèšå®ã¯ç°ãªããŸããããã³ç°ãªãç¶æ
ã§ã ããã«è©±ãé²ãããšãããã¯ãã§ã«ãããã¯ãã§ãŒã³ã«ã€ããŠã§ããããã®è©±ã®ãããã¯ã§ã¯ãããŸããã
ãããŠãGOãå®è¡ããŸã
ãã©ã°ã€ã³ã¡ã«ããºã ã䜿çšããããšã«ããŸããã 圌ã¯æ¬¡ã®ããšãè¡ãããã©ã°ã€ã³ãšãªããã®ãç¹å¥ãªæ¹æ³ã§å
±æã©ã€ãã©ãªã«ã³ã³ãã€ã«ãããããããŒãããŠã·ã³ãã«ãèŠã€ããããã§å®è¡ãæž¡ããŸãã ãã ããGOã«ã¯ã©ã³ã¿ã€ã ããããããã¯ã»ãŒ1ã¡ã¬ãã€ãã®ã³ãŒãã§ãããããã©ã«ãã§ã¯ãã®ã©ã³ã¿ã€ã ããã®ã©ã€ãã©ãªã«ç§»åãããã¹ãŠã®å Žæã«raznipipennyã©ã³ã¿ã€ã ããããŸãã ããããä»ãç§ãã¡ã¯å°æ¥ããããæã¡è² ããããšãã§ãããšç¢ºä¿¡ããŠããããéžã¶ããšã«ããŸããã
ã©ã€ãã©ãªãæ§ç¯ãããšãã¯ãã¹ãŠç°¡åã§ããããŒ-buildmode = pluginã§ãã«ããã.soãã¡ã€ã«ãååŸããŠéããŸãã
p, err := plugin.Open(path)
èå³ã®ãããã£ã©ã¯ã¿ãŒãæ¢ããŸãïŒ
symbol, err := p.Lookup(Method)
ãããŠä»ãå€æ°ãé¢æ°ã§ãããé¢æ°ã§ãããã«å¿ããŠããããåŒã³åºãããå€æ°ãšããŠäœ¿çšããŸãã
ãã®ã¡ã«ããºã ã®è£ã«ã¯ã·ã³ãã«ãªdlopenïŒ3ïŒããããã©ã€ãã©ãªãããŒãããŠãã©ã°ã€ã³ã§ããããšã確èªããã©ãããŒãäœæããŸããã©ãããŒãäœæãããšãããšã¯ã¹ããŒãããããã¹ãŠã®æåã¯ã€ã³ã¿ãŒãã§ã€ã¹{}ã«ã©ãããããŠä¿åãããŸãã é¢æ°ã®å Žåã¯ãæ£ããã¿ã€ãã®é¢æ°ã«æžãããŠãå€æ°ã®å Žåã¯åçŽã«åŒã³åºãå¿
èŠããããŸã-å€ââæ°ã®ããã«åäœããŸãã
èŠããŠããã¹ãäž»ãªããšã¯ãã·ã³ãã«ãå€æ°ã§ããå Žåãããã¯ããã»ã¹å
šäœã§ã°ããŒãã«ã§ãããããªãã¯ãããèããã«äœ¿çšã§ããªãããšã§ãã
ãã©ã°ã€ã³ã§åã宣èšãããŠããå Žåãããšãã°ããã©ã°ã€ã³ã®é¢æ°ã«åŒæ°ãšããŠæž¡ããªã©ãã¡ã€ã³ããã»ã¹ãåŠçã§ããããã«ããã®åãå¥ã®ããã±ãŒãžã«å
¥ããã®ãçã«ããªã£ãŠããŸãã ããã¯ãªãã·ã§ã³ã§ãããã¹ããŒã ãåå°ã䜿çšããããšã¯ã§ããŸããã
ã³ã³ãã©ã¯ãã¯å¯Ÿå¿ãããã¯ã©ã¹ãã®ãªããžã§ã¯ãã§ãããæåã¯ãã®ãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ããšã¯ã¹ããŒããããå€æ°ã«æ ŒçŽãããŠãããããå¥ã®åãå€æ°ãäœæã§ããŸãã
export, err := p.Lookup("EXPORT") obj := reflect.New(reflect.ValueOf(export).Elem().Type()).Interface()
ãããŠããã§ã«æ£ããåã®ãã®ããŒã«ã«å€æ°ã®å
éšã§ããªããžã§ã¯ãã®ç¶æ
ãéã·ãªã¢ã«åããŸãã ãªããžã§ã¯ãã埩å
ããããããã®ã¡ãœãããåŒã³åºãããšãã§ããŸãã ãã®åŸããªããžã§ã¯ããã·ãªã¢ã«åãããŠã¹ãã¢ã«åã³è¿œå ããããšãã³ã³ãã©ã¯ãã®ã¡ãœãããåŒã³åºããŸããã
æ¹æ³ã«èå³ãããããããã¥ã¡ã³ããèªãã®ãé¢åãããå ŽåïŒ
method := reflect.ValueOf(obj).MethodByName(Method) res:= method.Call(in)
éäžã§ãæ£ããé
åã®åŒæ°ãå«ã空ã®ã€ã³ã¿ãŒãã§ã€ã¹ãé
åã«å
¥åããå¿
èŠããããŸããèå³ãããå Žåã¯ããããã©ã®ããã«è¡ãããããåç
§ããŠãã ããããœãŒã¹ã¯éããŠããŸããã
å±¥æŽã§ãã®å ŽæãèŠã€ããããšã¯å°é£ã§ãã
äžè¬çã«ããã¹ãŠãç§ãã¡ã®ããã«åãããããªãã¯ã¯ã©ã¹ã®ãããªãã®ã§ã³ãŒããæžãããããã¯ãã§ãŒã³ã«ããã眮ãããããã¯ãã§ãŒã³äžã«ãã®ã¯ã©ã¹ã®ã³ã³ãã©ã¯ããåã³äœæããããã«å¯ŸããŠã¡ãœããåŒã³åºããè¡ããã³ã³ãã©ã¯ãã®æ°ããç¶æ
ããããã¯ãã§ãŒã³ã«æžãæ»ãããããšãã§ããŸã ãããïŒ æå
ã®ã³ãŒãã§æ°ããå¥çŽãäœæããæ¹æ³ã¯ïŒ éåžžã«ç°¡åã§ããæ°ããäœæããããªããžã§ã¯ããè¿ãã³ã³ã¹ãã©ã¯ã¿é¢æ°ããããŸããããã¯æ°ããã³ã³ãã©ã¯ãã§ãã ãããŸã§ã®ãšããããã¹ãŠã¯ãªãã¬ã¯ã·ã§ã³ã«ãã£ãŠæ©èœãããŠãŒã¶ãŒã¯æ¬¡ã®ããã«èšè¿°ããå¿
èŠããããŸãã
var EXPORT ContractType
ãã®ãããã©ã®ã·ã³ãã«ãã³ã³ãã©ã¯ãã®è¡šçŸã§ããããããããå®éã«ã¯ããããã³ãã¬ãŒããšããŠäœ¿çšãããŸããã
ããŸã奜ãã§ã¯ãããŸããã ãããŠãç§ãã¡ã¯æ¿ããå©ããŸããã
解æ
第äžã«ããŠãŒã¶ãŒã¯äœèšãªãã®ãæžãã¹ãã§ã¯ãªãã第äºã«ãã³ã³ãã©ã¯ããšã³ã³ãã©ã¯ãã®çžäºäœçšã¯ã·ã³ãã«ã§ããããã¯ãã§ãŒã³ãäžããããšãªããã¹ããããã¹ãã ãšããèããæã£ãŠããŸãããããã¯ãã§ãŒã³ã¯é
ããŠé£ããã§ãã
ãããã£ãŠãåºæ¬çã«ã¯ç解å¯èœãªãœãªã¥ãŒã·ã§ã³ã§ããã³ã³ãã©ã¯ããšã©ãããŒãã³ãã¬ãŒãã«åºã¥ããŠçæãããã©ãããŒã§ã³ã³ãã©ã¯ããã©ããããããšã«ããŸããã ãŸããã©ãããŒã¯ãšã¯ã¹ããŒããªããžã§ã¯ããäœæãã次ã«ããŠãŒã¶ãŒãå¥çŽãäœæãããšãã«å¥çŽãåéãããã©ã€ãã©ãªã眮ãæããŸããåºç€ã©ã€ãã©ãªã¯å
éšã®mokaã§äœ¿çšãããå¥çŽãå
¬éããããšããããã¯ãã§ãŒã³èªäœã§æ©èœããæŠéã«çœ®ãæããããŸãã
ãŸããã³ãŒãã解æããäžè¬çã«äœãæã£ãŠããããç解ããBaseContractããç¶æ¿ãããæ§é ãèŠã€ããŠããã®åšãã®ã©ãããŒãçæããå¿
èŠããããŸãã
ããã¯éåžžã«ç°¡åã«è¡ãããŸãã[]ãã€ãã®ã³ãŒãã§ãã¡ã€ã«ãèªã¿åããŸãããããŒãµãŒèªäœã¯ãã¡ã€ã«ãèªã¿åãããšãã§ããŸããããã¹ãŠã®ASTèŠçŽ ãåç
§ããããã¹ããã©ããã«ããããã¡ã€ã«å
ã®ãã€ãçªå·ãåç
§ããããã«åãåãããæ§é ã³ãŒãã¯ãã®ãŸãŸã§ã次ã®ãããªãã®ãåããŸãã
func (pf *ParsedFile) codeOfNode(n ast.Node) string { return string(pf.code[n.Pos()-1 : n.End()-1]) }
å®éã«ãã¡ã€ã«ã解æããæäžäœã®ASTããŒããååŸããŠããããããã¡ã€ã«ãã¯ããŒã«ããŸãã
fileSet = token.NewFileSet() node, err := parser.ParseFile(fileSet, name, code, parser.ParseComments)
次ã«ãæäžäœããŒãããå§ããŠã³ãŒãã調ã¹ãŠãèå³æ·±ããã®ããã¹ãŠå¥ã®æ§é ã«åéããŸãã
for _, decl := range node.Decls { switch d := decl.(type) { case *ast.GenDecl: ⊠case *ast.FuncDecl: ⊠} }
宣èšããã¡ã€ã«ã«å®çŸ©ãããŠãããã¹ãŠã®ãªã¹ãã§ããé
åã«æ¢ã«è§£æãããŠããŸãããå
éšã®å
容ãèšè¿°ããªãDeclã€ã³ã¿ãŒãã§ãŒã¹ã®é
åã§ãããããåèŠçŽ ã¯ç¹å®ã®åã«å€æããå¿
èŠããããŸãã go / astã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ããããåºæ¬ã¯ã©ã¹ã§ãã
GenDeclããã³FuncDeclã¿ã€ãã®ããŒãã«èå³ããããŸãã GenDeclã¯å€æ°ãŸãã¯åã®å®çŸ©ã§ãããå
éšã®åãäœã§ããããæ£ç¢ºã«ç¢ºèªããããäžåºŠæäœã§ããTypeDeclåã«ãã£ã¹ãããå¿
èŠããããŸãã FuncDeclã¯ããåçŽã§ããããã¯é¢æ°ã§ãããRecvãã£ãŒã«ããå
¥åãããŠããå Žåã察å¿ããæ§é ã®ã¡ãœããã§ãã ããã¹ã/ãã³ââãã¬ãŒãã䜿çšããè¡šçŸåãããŸããªããããããããã¹ãŠã䟿å©ãªã¹ãã¬ãŒãžã«åéããŸãã
åå¥ã«èŠããŠããå¿
èŠãããã®ã¯ãBaseContractããç¶æ¿ãããããŒã¿åã®ååã ãã§ããããã®åšãã§èžããŸãã
ã³ãŒãçæ
ãã®ãããã³ã³ãã©ã¯ãã«å«ãŸãããã¹ãŠã®åãšé¢æ°ãç¥ã£ãŠãããçä¿¡ã¡ãœããåãšåŒæ°ã®ã·ãªã¢ã«åãããé
åãããªããžã§ã¯ãã«å¯ŸããŠã¡ãœããåŒã³åºããè¡ãããšãã§ããå¿
èŠããããŸãã ããããçµå±ã®ãšãããã³ãŒãçæã®æç¹ã§ã¯ãå¥çŽã®ããã€ã¹å
šäœãããã£ãŠããã®ã§ãå¥çŽãã¡ã€ã«ã®é£ã«ãåãããã±ãŒãžåãæã€å¥ã®ãã¡ã€ã«ã®é£ã«çœ®ããããã«å¿
èŠãªãã¹ãŠã®ã€ã³ããŒããå
¥ããŸããã¿ã€ãã¯ãã§ã«ã¡ã€ã³ãã¡ã€ã«ã§å®çŸ©ãããŠãããäžèŠã§ãã
ãããŠããããäž»ãªãã®ã§ãããé¢æ°ã®ã©ãããŒã§ãã ã©ãããŒã®ååã¯ããçš®ã®ãã¬ãã£ãã¯ã¹ã§è£å®ãããã©ãããŒã¯ç°¡åã«èŠã€ããããããã«ãªããŸããã
symbol, err := p.Lookup("INSMETHOD_" + Method) wrapper, ok := symbol.(func(ph proxyctx.ProxyHelper, object []byte, data []byte) (object []byte, result []byte, err error))
åã©ãããŒã«ã¯åãã·ã°ããã£ããããããã¡ã€ã³ããã°ã©ã ããåŒã³åºãå Žåãäœåãªãªãã¬ã¯ã·ã§ã³ã¯å¿
èŠãããŸãããå¯äžã®ããšã¯ãé¢æ°ã©ãããŒãã¡ãœããã©ãããŒãšç°ãªãããšã§ããããªããžã§ã¯ãã®ç¶æ
ãåãåã£ããè¿ãããããŸããã
ã©ãããŒã®äžã«ã¯äœããããŸããïŒ
é¢æ°ã®åŒæ°ã«å¯Ÿå¿ãã空ã®å€æ°ã®é
åãäœæããã€ã³ã¿ãŒãã§ã€ã¹ã®é
åã®åã®å€æ°ã«å
¥ããåŒæ°ãéã·ãªã¢ã«åããŸããã¡ãœããã®å Žåã¯ããªããžã§ã¯ãã®ç¶æ
ãã·ãªã¢ã«åããå¿
èŠããããŸãã
{{ range $method := .Methods }} func INSMETHOD_{{ $method.Name }}(ph proxyctx.ProxyHelper, object []byte, data []byte) ([]byte, []byte, error) { self := new({{ $.ContractType }}) err := ph.Deserialize(object, self) if err != nil { return nil, nil, err } {{ $method.ArgumentsZeroList }} err = ph.Deserialize(data, &args) if err != nil { return nil, nil, err } {{ if $method.Results }} {{ $method.Results }} := self.{{ $method.Name }}( {{ $method.Arguments }} ) {{ else }} self.{{ $method.Name }}( {{ $method.Arguments }} ) {{ end }} state := []byte{} err = ph.Serialize(self, &state) if err != nil { return nil, nil, err } {{ range $i := $method.ErrorInterfaceInRes }} ret{{ $i }} = ph.MakeErrorSerializable(ret{{ $i }}) {{ end }} ret := []byte{} err = ph.Serialize([]interface{} { {{ $method.Results }} }, &ret) return state, ret, err } {{ end }}
泚ææ·±ãèªè
ã¯ããããã·ãã«ããŒãšã¯äœãã«èå³ããããŸããïŒ -ããã¯ãŸã å¿
èŠãªçµââåãªããžã§ã¯ãã§ãããçŸæç¹ã§ã¯ãã·ãªã¢ã«åãšéã·ãªã¢ã«åã®æ©èœã䜿çšããŠããŸãã
ããŠãèªãã§ãã人ã¯èª°ã§ãããããããããã¯ããªãã®è°è«ã§ããã©ãããæ¥ãã®ã§ããïŒããšå°ããã§ããããããã«ãæ確ãªçãããããŸããã¯ãã空ããã®ååãªããã¹ã/ãã³ââãã¬ãŒãã®æã¯ãããŸããã
method.ArgumentsZeroListã«ã¯æ¬¡ã®ãããªãã®ãå«ãŸããŸã
var arg0 int = 0 Var arg1 string = ââ Var arg2 ackwardType = ackwardType{} Args := []interface{}{&arg0, &arg1, &arg2}
ãŸããåŒæ°ã«ã¯ãarg0ãarg1ãarg2ããå«ãŸããŸãã
ãããã£ãŠãä»»æã®çœ²åã䜿çšããŠãå¿
èŠãªãã®ãåŒã³åºãããšãã§ããŸãã
ããããçããã·ãªã¢ã«åããããšã¯ã§ããŸãããäºå®ãã·ãªã¢ã©ã€ã¶ãŒã¯ãªãã¬ã¯ã·ã§ã³ã§åäœãããšã¯ã¹ããŒããããŠããªãæ§é äœã®ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ã§ããªãããããšã©ãŒã€ã³ã¿ãŒãã§ã€ã¹ãªããžã§ã¯ããååŸããããããåã®åºç€ã®ãªããžã§ã¯ããäœæããç¹å¥ãªãããã·ãã«ããŒã¡ãœããããããŸãããšã©ãŒãéåžžã®ãšã©ãŒãšã¯ç°ãªãããšã¯ã¹ããŒãããããã£ãŒã«ãã«ãšã©ãŒããã¹ããå«ãŸããŠãããããå€å°ã®æ倱ã¯ãããŸãããã·ãªã¢ã«åã§ããŸãã
ããããã³ãŒãçæã®æ»
èåšã䜿çšããå Žåããããå¿
èŠãããŸãããåãããã±ãŒãžã§ã³ã³ãã€ã«ããããšã¯ã¹ããŒããããŠããªããã£ãŒã«ãã«ã¢ã¯ã»ã¹ã§ããŸãã
ããããå¥çŽããå¥çŽãåŒã³åºãããå Žåã¯ã©ãã§ããããïŒ
å¥çŽããå¥çŽãåŒã³åºãã®ãç°¡åã ãšæããšãåé¡ã®æ·±ããç解ã§ããŸããã äºå®ã¯ãã³ã³ã»ã³ãµã¹ã«ãã£ãŠå¥ã®å¥çŽã®æå¹æ§ã確èªããå¿
èŠãããããã®åŒã³åºãã®äºå®ã¯ãããã¯ãã§ãŒã³ã§çœ²åããå¿
èŠããããäžè¬ã«ãåã«å¥ã®å¥çŽã§ã³ã³ãã€ã«ããŠãã®ã¡ãœãããåŒã³åºãããšã¯æ©èœããŸããããæ¬åœã«ãããã®ã§ããã ããããç§ãã¡ã¯ããã°ã©ããŒã®å人ãªã®ã§ããã¹ãŠãçŽæ¥è¡ãæ©äŒãäžããã·ã¹ãã ã®å
éšã«ãã¹ãŠã®ããªãã¯ãé ãå¿
èŠããããŸãã ãããã£ãŠãå¥çŽã®éçºã¯çŽæ¥åŒã³åºãã®ããã«å®è¡ãããå¥çŽã¯äºãã«ééçã«åŒãåããŸãããå
¬éã®ããã«å¥çŽãåéããå Žåãå¥ã®å¥çŽã®ä»£ããã«ãããã·ãã¹ãªããããŸããããã¯ãå¥çŽã«é¢ããã¢ãã¬ã¹ãšåŒã³åºã眲åã®ã¿ãç¥ã£ãŠããŸãã
ããããã¹ãŠæŽçããæ¹æ³ã¯ïŒ -ãžã§ãã¬ãŒã¿ãŒãã€ã³ããŒããããåå¥çŽã®ãããã·ãèªèããŠäœæã§ããããã«ãç¹å¥ãªãã£ã¬ã¯ããªã«ä»ã®å¥çŽãä¿åããå¿
èŠããããŸãã
ã€ãŸããäŒã£ãå ŽåïŒ
import âContractsDir/ContractAddress"
ã€ã³ããŒããããå¥çŽã®ãªã¹ãã«æžã蟌ã¿ãŸãã
ã¡ãªã¿ã«ããã®ããã«å¥çŽã®ãœãŒã¹ã³ãŒããç¥ãå¿
èŠã¯ãããŸãããæ¢ã«åéãã説æãç¥ã£ãŠããå¿
èŠãããã ãã§ãããã®ãããªèª¬æãã©ããã«å
¬éãããã¹ãŠã®åŒã³åºããã¡ã€ã³ã·ã¹ãã ãééããå Žåãå¥ã®ã³ã³ãã©ã¯ããèšèªã§èšè¿°ããããã®ã¡ãœãããåŒã³åºãããšãã§ããå ŽåãGoã§ãã®ã¹ã¿ããèšè¿°ã§ããŸããããã¯ãçŽæ¥åŒã³åºãããšãã§ããã³ã³ãã©ã¯ããæã€ããã±ãŒãžã®ããã«èŠããŸãã ããã¬ãªã³ã®èšç»ãå®è£
ã«åãââæãããã
ååãšããŠããã®ã·ã°ããã£ãæã€ãããã·ãã«ããŒã¡ãœãããæ¢ã«ãããŸãã
RouteCall(ref Address, method string, args []byte) ([]byte, error)
ãã®ã¡ãœããã¯ã³ã³ãã©ã¯ãããçŽæ¥åŒã³åºãããšãã§ãããªã¢ãŒãã³ã³ãã©ã¯ããåŒã³åºãã解æããŠã³ã³ãã©ã¯ãã«æ»ãå¿
èŠãããã·ãªã¢ã«åãããå¿çãè¿ããŸãã
ãã ãããŠãŒã¶ãŒã¯ãã¹ãŠæ¬¡ã®ããã«èŠããå¿
èŠããããŸãã
ret := contractPackage.GetObject(Address).Method(arg1,arg2, âŠ)
ãŸãããããã·ã§ãã³ã³ãã©ã¯ãã¡ãœããã®ã·ã°ããã£ã§äœ¿çšããããã¹ãŠã®ã¿ã€ãããªã¹ãããå¿
èŠããããŸãããèŠããŠããããã«ãåASTããŒãã«å¯ŸããŠãã®ããã¹ãè¡šçŸãååŸã§ããŸãããããŠããã®ã¡ã«ããºã ã®æãæ¥ãŸããã
次ã«ãããã¿ã€ãã®å¥çŽãäœæããå¿
èŠããããŸããååãšããŠã圌ã¯ãã§ã«ã¯ã©ã¹ãç¥ã£ãŠãããäœæã®ã¿ãå¿
èŠã§ãã
type {{ .ContractType }} struct { Reference Address }
次ã«ãäœããã®æ¹æ³ã§GetObjecté¢æ°ãå®è£
ããå¿
èŠããããŸããGetObjecté¢æ°ã¯ããããã¯ãã§ãŒã³äžã®ã¢ãã¬ã¹ã§ããã®ã³ã³ãã©ã¯ãã®æäœæ¹æ³ãç¥ã£ãŠãããããã·ã€ã³ã¹ã¿ã³ã¹ãè¿ãããŠãŒã¶ãŒã«ãšã£ãŠã¯ã³ã³ãã©ã¯ãã€ã³ã¹ã¿ã³ã¹ã®ããã«èŠããŸãã
func GetObject(ref Address) (r *{{ .ContractType }}) { return &{{ .ContractType }}{Reference: ref} }
èå³æ·±ãããšã«ããŠãŒã¶ãŒãããã°ã¢ãŒãã®GetObjectã¡ãœããã¯çŽæ¥BaseContractæ§é äœã¡ãœããã§ãããããã§ã¯ãSLAã芳å¯ããŠã䟿å©ãªããšãè¡ãããšã劚ãããã®ã¯äœããããŸããã ããã§ãå¶åŸ¡ããã¡ãœããã§ãããããã·ã³ã³ãã©ã¯ããäœæã§ããŸãã å®éã«ã¡ãœãããäœæããããšã¯æ®ã£ãŠããŸãã
{{ range $method := .MethodsProxies }} func (r *{{ $.ContractType }}) {{ $method.Name }}( {{ $method.Arguments }} ) ( {{ $method.ResultsTypes }} ) { {{ $method.InitArgs }} var argsSerialized []byte err := proxyctx.Current.Serialize(args, &argsSerialized) if err != nil { panic(err) } res, err := proxyctx.Current.RouteCall(r.Reference, "{{ $method.Name }}", argsSerialized) if err != nil { panic(err) } {{ $method.ResultZeroList }} err = proxyctx.Current.Deserialize(res, &resList) if err != nil { panic(err) } return {{ $method.Results }} } {{ end }}
ããã§åŒæ°ãªã¹ãã®æ§ç¯ãšåã話ãããŸããç§ãã¡ã¯æ ãè
ã§ã¡ãœããã®ast.Nodeãæ£ç¢ºã«ä¿åããŠãããããèšç®ã«ã¯ãã³ãã¬ãŒããç¥ããªãå€ãã®åå€æãå¿
èŠãªã®ã§ããã¹ãŠãäºåã«æºåãããŸãã é¢æ°ã䜿çšãããšããã¹ãŠãéåžžã«è€éã«ãªããŸããããã¯å¥ã®èšäºã®ãããã¯ã§ãã
ç§ãã¡ãæã£ãŠããæ©èœã¯ãªããžã§ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§ãããã·ã¹ãã ã§ãªããžã§ã¯ããå®éã«äœæãããæ¹æ³ã«å€ãã®éç¹ã眮ãããŠããŸããäœæã®äºå®ã¯ãªã¢ãŒããšã°ãŒãã¥ãŒã¿ãŒã«ç»é²ããããªããžã§ã¯ãã¯å¥ã®ãšã°ãŒãã¥ãŒã¿ãŒã«è»¢éããããã§ãã¯ãããŠå®éã«ããã«ä¿åããããããŠç¡é§ã«å€ãã®ä¿åæ¹æ³ããããŸããã®ç¥èã®é åã¯æå·ãšåŒã°ããŸãã ãããŠããã®èãæ¹ã¯åºæ¬çã«ã·ã³ãã«ã§ãã¢ãã¬ã¹ã®ã¿ãä¿åãããã©ãããŒãšãåŒã³åºããã·ãªã¢ã«åããæ®ããå®è¡ããã·ã³ã°ã«ãã³ã³ã³ãã€ã³ããã«ããã¡ãœããã§ãã éä¿¡ããããããã·ãã«ããŒã¯äœ¿çšã§ããŸããããŠãŒã¶ãŒããæž¡ãããªãã£ããããã·ã³ã°ã«ãã³ã«ããå¿
èŠããããŸããã
å¥ã®ããªãã¯-å®éãç§ãã¡ã¯ãŸã åŒã³åºãã³ã³ããã¹ãã䜿çšããŠããŸããããã¯ã誰ãããã€ããªãããªãç§ãã¡ã®ã¹ããŒãã³ã³ãã©ã¯ããåŒã³åºããããã«é¢ããæ
å ±ãæ ŒçŽãããªããžã§ã¯ãã§ããããã®æ
å ±ã«åºã¥ããŠããŠãŒã¶ãŒã¯å®è¡ãäžãããã©ããã決å®ããå¯èœã§ããã°ãã®åŸãã©ã®ããã«ã
以åã¯ãåã«ã³ã³ããã¹ããæž¡ããŸãããããã¯ãã»ãã¿ãŒãšã²ãã¿ãŒãæã€BaseContractåã®è¡šçŸã§ããªããã£ãŒã«ãã§ãããã»ãã¿ãŒã¯ãã£ãŒã«ãã®èšå®ã1åã®ã¿èš±å¯ãããããã³ã³ãã©ã¯ããå®è¡ãããåã«ã³ã³ããã¹ããèšå®ããããŠãŒã¶ãŒã¯ãããèªã¿åãããšããã§ããŸããã§ããã
ããããããã«åé¡ããããŸãããŠãŒã¶ãŒããã®ã³ã³ããã¹ããèªãã®ã¯ãããçš®ã®ã·ã¹ãã é¢æ°ïŒããšãã°ãå¥ã®ã³ã³ãã©ã¯ããžã®ãããã·åŒã³åºãïŒãåŒã³åºããå Žåã ãã§ãããã®ãããã·åŒã³åºãã¯èª°ã«ãæž¡ãããªããããã³ã³ããã¹ããåãåããŸããã ãããŠããŽã«ãŒãã³ã®ããŒã«ã«ã¹ãã¬ãŒãžãç»å ŽããŸãã ç¬èªã«äœæããããšã¯ãããgithub.com / tylerb / glsã䜿çšããããšã«ããŸããã
çŸåšã®ãŽã«ãŒãã³ã®ã³ã³ããã¹ããèšå®ããã³ååŸã§ããŸãã ãããã£ãŠãã³ã³ãã©ã¯ãå
ã«ãŽã«ãŒãã³ãäœæãããŠããªãå Žåãã³ã³ãã©ã¯ããéå§ããåã«ã³ã³ããã¹ããglsã«èšå®ããã ãã§ãã¡ãœããã§ã¯ãªãé¢æ°ã®ã¿ããŠãŒã¶ãŒã«æäŸããŸãã
func GetContext() *core.LogicCallContext { return gls.Get("ctx").(*core.LogicCallContext) }
ãããŠåœŒã¯ãããåãã§äœ¿çšããŠããŸãããããšãã°ãã©ã®å¥çŽãçŸåšèª°ããåŒã³åºããŠããããç解ããããã«ãRouteCallïŒïŒã§äœ¿çšããŸãã
ååãšããŠããŠãŒã¶ãŒã¯ãŽã«ãŒãã³ãäœæã§ããŸãããäœæãããšã³ã³ããã¹ãã倱ããããããããšãã°ããŠãŒã¶ãŒãgoããŒã¯ãŒãã䜿çšããå Žåããã®ãããªåŒã³åºããã©ãããŒã§ã©ããããå¿
èŠããããŸãã goroutineãšãã®ã³ã³ããã¹ãã埩å
ããŸãããããã¯å¥ã®èšäºã®ãããã¯ã§ãã
ãã¹ãŠäžç·ã«
ç§ãã¡ã¯åºæ¬çã«GOèšèªããŒã«ãã§ãŒã³ã®ä»çµã¿ã奜ãã§ããå®éãããã¯ãããšãã°ãã«ããè¡ããšãã«äžç·ã«å®è¡ãããã1ã€ã®ããšãè¡ãããŸããŸãªã³ãã³ãã®éãŸãã§ãã åãããšãããããšã«ããŸãã.1ã€ã®ããŒã ãå¥çŽãã¡ã€ã«ãäžæãã£ã¬ã¯ããªã«é
眮ãã2çªç®ã®ããŒã ããã®ã©ãããŒãé
眮ããŠ3åç®ã®åŒã³åºããè¡ããã€ã³ããŒããããåå¥çŽã®ãããã·ãäœæãã4çªç®ããã¹ãŠãã³ã³ãã€ã«ãã5çªç®ããããã¯ãã§ãŒã³ã«å
¬éããŸãã ãããŠããã¹ãŠãæ£ããé åºã§å®è¡ããã³ãã³ãã1ã€ãããŸãã
ãããGOããGOãèµ·åããããã®ããŒã«ãã§ãŒã³ãšã©ã³ã¿ã€ã ãã§ããŸããã ãŸã å€ãã®åé¡ããããŸããããšãã°ãæªäœ¿çšã®ã³ãŒããäœããã®æ¹æ³ã§ã¢ã³ããŒãããå¿
èŠããããåæ¢ããããã»ã¹ããã³ã°ããŠåèµ·åããããšãäœããã®æ¹æ³ã§å€æããå¿
èŠããããŸããããããã¯è§£æ±ºæ¹æ³ãæ確ãªã¿ã¹ã¯ã§ãã
ã¯ãããã¡ãããç§ãã¡ãæžããã³ãŒãã¯ã©ã€ãã©ãªã®ãµããããŠããªãã®ã§ãçŽæ¥äœ¿çšããããšã¯ã§ããŸããããåäœããã³ãŒãçæã®äŸãèªãããšã¯åžžã«çŽ æŽãããã§ãã ãããã£ãŠãã³ãŒãçæã®äžéšã¯
ã³ã³ãã€ã©ãŒã§èŠãããšãã§ããŸããã
ãšã°ãŒãã¥ãŒã¿ãŒã§ã©ã®ããã«éå§ãããã§ãã