Slide 1

Slide 1 text

֊૚తܾఆੑ΢ΥϨοτͷ࣮૷ m / purpose' / coin_type' / account' / change / address_index

Slide 2

Slide 2 text

Abount Me • Twi%er ˏkogane5513 • 2018/10ʙɹϚωʔϑΥϫʔυϑΟφϯγϟϧ • Ծ૝௨՟औҾॴͷ৽ن։ઃʹ޲͚ͯฃಆதʂ • ʙ2018/9 • ʢגʣSmartDrive • ৽نࣄۀ։ൃ • freee גࣜձࣾʢϑϦʔʣ • ܾࡁɺೝূج൫νʔϜ

Slide 3

Slide 3 text

ຊ೔ͷ಺༰ • ֊૚తܾఆੑ΢ΥϨοτͱ͸(BIP32,44) • ֊૚తܾఆੑ΢ΥϨοτͷ࣮૷ • Mul.Sig Addressͷ࣮૷ ࢖༻ݴޠɿGolang ࢖༻ϥΠϒϥϦʔɿbtcsuite/btcu/l import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcu/l/hdkeychain" "github.com/btcsuite/btcd/txscript" )

Slide 4

Slide 4 text

֊૚తܾఆੑ΢ΥϨοτͱ͸(BIP32,BIP44) ϚελʔͳΔγʔυ஋͔Βɺm/i/0/kͷΑ͏ͳ֊૚ߏ଄తʹൿີ伴Λੜ੒ɾ؅ཧͰ͖Δඪ४ن֨Ͱ͢ɻ ʢHierarchical Determinis2c Wallet = HD Walletʣ ௨ৗͷ΢ΥϨοτͰ͸ɺ࢖༻ࡁΈͷൿີ伴ͱެ։伴ͷϖΞΛఆظతʹɺ͢΂ͯόοΫΞοϓ͓ͯ͘͠ඞཁ͕͋Γ·͕ͨ͠ɺBIP32Ͱ ඪ४Խ͞ΕͨϓϩτίϧΛར༻͢Δ͜ͱͰɺϚελʔγʔυ͑͞อଘ͞Ε͍ͯΕ͹ɺ͔ͦ͜Β೿ੜ͢Δൿີ伴Λ͍࣋ͬͯͳͯ͘΋Π ϯσοΫεΛࢦఆ͢Δ͜ͱͰɺҟͳΔγεςϜ͔Β͍ͭͰ΋࠶ར༻͢Δ͜ͱ͕Ͱ͖·͢ɻ ϏοτίΠϯίΞʹ΋v0.13.0͔Βಋೖ͞Εɺਖ਼ࣜʹαϙʔτ͞ΕΔΑ͏ʹͳΓ·ͨ͠ɻ ͭ·ΓɺHD Walletͷن֨Ͱੜ੒͞Εͨൿີ伴Ͱ͋Ε͹ɺSeed͑͋͞Ε͹෮ݩɺ࠶ར༻ՄೳͱͳΓӡ༻ָ͕ʹͳΔͱ͍͏΋ͷɻ 1ݸͷཚ਺͔ΒπϦʔߏ଄తʹଟ਺ΞυϨεʢൿີ伴ɺެ։伴ʣΛੜ੒Ͱ͖·͢ɻ Լه͸ɺ֊૚Խ͞ΕͨύεͷΠϝʔδͰ͢ɻ • BIP32 Path level:Ϛελʔ / ΞΧ΢ϯτ' / ࢧ෷͍ or ͓௼Γ / ΞυϨε • BIP44 Path level: Ϛελʔ / ࢓༷(BIP)' / ௨՟' / ΞΧ΢ϯτ' / ࢧ෷͍ or ͓௼Γ / ΞυϨε

Slide 5

Slide 5 text

֊૚తܾఆੑ΢ΥϨοτͱ͸(BIP32,BIP44) ֊૚ผʹΑΔ࢓༷͸ԼهʹͳΓ·͢ɻ m: Ϛελʔ伴 purpose: ໨త֊૚ 44ʹઃఆ͞Εͨఆ਺ cointype: ίΠϯͷछྨ֊૚ɻ௨՟ຖʹεϖʔε͕ܾΊΒΕ͍ͯΔ account: ࢖༻໨త֊૚ɻد෇໨త / ஷ஝໨త / ڞ௨ܦඅ ͳͲ࢖༻͢ΔϢʔβʔଆͰܾΊΔ͜ͱ͕Ͱ͖Δ change: डऔ֊૚ɻ֎෦ૹۚऀʢExternalʣ͔ΒͷडऔΓ͕0 / ࣗ਎ʢInternalʣͷτϥϯβΫγϣϯ͔Βͷ͓ͭΓͷडऔΓ͕1 addressindex: ΞυϨε֊૚ɻΠϯσοΫε஋͕ৼΒΕΔ Coin types Path Examples

Slide 6

Slide 6 text

γʔυͷੜ੒ جຊతʹHD Walletͷ࣮૷Ͱ͸ɺhdkeychainύοέʔδʹ༻ҙ͞Ε͍ͯ·͢ɻ γʔυͷੜ੒΋͜ͷύοέʔδʹ͋ΔGenerateSeedϑΝϯΫγϣϯΛ࢖͑͹Αͯ͘ɺ γʔυͷ௕͞͸BIP-0032Ͱਪ঑͞Ε͍ͯΔόΠτ୯Ґͷ௕͞(256bitsɿ128bitsʙ512bits)΋ఆ਺ͱͯ͠ఆٛ͞Ε͍ͯ·͢ import ( "github.com/btcsuite/btcutil/hdkeychain" ) seed, err := hdkeychain.GenerateSeed(hdkeychain.RecommendedSeedLen) if err != nil { return err }

Slide 7

Slide 7 text

Ϛελʔ伴 γʔυΛར༻ͯ͠Ϛελʔ伴Λੜ੒͠·͢ɻ ·ͨɺςετωοτͷ৔߹ɺୈೋҾ਺ʹ౉͢΋ͷ͸chaincfgύοέʔδʹ༻ҙ͞Ε͍ͯΔchaincfg.TestNet3ParamsΛηοτͯͩ͘͠ ͍͞ɻ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil/hdkeychain" ) master, err := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) if err != nil { return err }

Slide 8

Slide 8 text

Purpose ͜͜Ͱ͸Ͳͷ࢓༷(BIP)ʹै͍ͬͯΔ͔Λࣔ͢ɻ·ͨɺڧԽ伴ಋग़ͷͨΊΠϯσοΫε஋ʹ2³¹ΛՃࢉ͠·͢ɻ ڧԽ伴ಋग़ʁ 1ͭͰ΋ϏοτίΠϯΞυϨεͷൿີ伴͕ྲྀग़ͯ͠͠·͏ͱɺಉ͡ϒϥϯνͷൿີ伴Λશͯࢉग़͞Εͯ͠·͏੬ऑੑ͕͋ΓɺڧԽಋ ग़ؔ਺Ληοτ͢Δͱɺ͜ͷ੬ऑੑΛճආͰ͖ΔΒ͍͠ɻ import ( "github.com/btcsuite/btcutil/hdkeychain" ) // m/44' // BIP-49(P2SHでネストされたP2WPKHアドレス導出する場合は、49??) purpose, err := master.Child(44 + hdkeychain.HardenedKeyStart) if err != nil { return err }

Slide 9

Slide 9 text

CoinType ͜͜Ͱ͸Ͳͷ௨՟ʹै͍ͬͯΔ͔Λࣔ͢ɻ·ͨɺ͜͜Ͱ΋ڧԽ伴ಋग़ͷͨΊΠϯσοΫε஋ʹ2³¹ΛՃࢉ͠·͢ɻ import ( "github.com/btcsuite/btcutil/hdkeychain" ) // m/44'/0' coinType, err := purpose.Child(0 + hdkeychain.HardenedKeyStart) if err != nil { return err }

Slide 10

Slide 10 text

Account ΞΧ΢ϯτΛࣔ͢ΠϯσοΫεΛࢦఆ͢Δɻ·ͨɺڧԽ伴ಋग़ͷͨΊΠϯσοΫε஋ʹ2³¹ΛՃࢉ͢Δ import ( "github.com/btcsuite/btcutil/hdkeychain" ) // m/44'/0'/0' account, err := coinType.Child(1 + hdkeychain.HardenedKeyStart) if err != nil { return err }

Slide 11

Slide 11 text

ΤΫελʔφϧ/Πϯλʔφϧ ͜͜Ͱ͸ࢧ෷͍=0ɺ͓ͭΓ༻=1ͷ͍ͮΕ͔Λࣔ͢ import ( "github.com/btcsuite/btcutil/hdkeychain" ) // m/44'/0'/0'/0 change, err := account.Child(0) if err != nil { return err }

Slide 12

Slide 12 text

Addess Index ͕͜͜຤୺ͱͳΓ͜͜Ͱੜ੒͞Εͨެ։伴Λ࢖ͬͯΞυϨεΛੜ੒͢Δ import ( "github.com/btcsuite/btcutil/hdkeychain" ) // m/44'/0'/0'/0/0 addressIndex, err := change.Child(0) if err != nil { return err } addressIndex.ECPubKey() // 公開鍵

Slide 13

Slide 13 text

Mul$Sig Addressͷ࣮૷ // AddressPubKeyを使ってredeemScriptを作成する addressPubKeys := []*btcutil.AddressPubKey{addressPubKey1, addressPubKey2} // 2 of 2 redeemScript, err := txscript.MultiSigScript(addressPubKeys, len(addressPubKeys)) if err != nil { return err } // redeemScriptよりMultiSig adddressを作成する ad, err := btcutil.NewAddressScriptHash(redeemScript, &chaincfg.MainNetParams) if err != nil { return err } addr := ad.EncodeAddress()

Slide 14

Slide 14 text

Mul$Sig Addressͷ࣮૷ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error) { if len(pubkeys) < nrequired { str := fmt.Sprintf("unable to generate multisig script with "+ "%d required signatures when there are only %d public "+ "keys available", nrequired, len(pubkeys)) return nil, scriptError(ErrTooManyRequiredSigs, str) } builder := NewScriptBuilder().AddInt64(int64(nrequired)) for _, key := range pubkeys { builder.AddData(key.ScriptAddress()) } builder.AddInt64(int64(len(pubkeys))) builder.AddOp(OP_CHECKMULTISIG) return builder.Script() }

Slide 15

Slide 15 text

No content