вторник, 26 марта 2019 г.

Связь GUI (web) и смарт-контракта.

Видео-туториал тут: https://www.youtube.com/watch?v=hcTPjpPvas8

Парочка замечаний:

1. Устанавливать надо версию web3 0.20.6 (в версии 0.20.7 можем получить ошибку: Access to XMLHttpRequest at 'http://localhost:8545/' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.)

2. Чтобы установился dist\web3.min.js нужно при установке добавлять ключ --verbose.

Резюмируя: npm install web3@0.20.6 --save --verbose

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru

понедельник, 25 марта 2019 г.

Первый Smart Contract

Годное введение здесь: Build Your First Ethereum Smart Contract with Solidity

Пара замечаний:

1. Для подсоединения к запущенной ноде надо использовать:

    geth attach ipc:\\.\pipe\geth.ipc

Если же просто выполнить geth attach, то получим ошибку: Unable to attach to remote geth: no known transport for URL scheme "c" (это верно для версии geth 1.8.23).

2. Mist лучше устанавливать 0.9.3, а не 0.11.1. В последнем при попытке вызвать методы созданного смарт контракта выводится ошибка: Couldn't estimate gas, resorting to default parameters. Transaction is likely cheaper than the estimate. И в дальнейшем состояние "counter" контракта из примера не изменяется (остается всегда 5). В версии Mist 0.9.3 все OK.

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru

четверг, 11 января 2018 г.

воскресенье, 6 августа 2017 г.

[Delphi XE2] MD4/MD5 Bug on x64

В библиотеке Indy, которая поставляется с  Delphi XE2 под 64-битной платформой, имеется баг в вычислении MD4/MD5 (компоненты TIdHashMessageDigest4, TIdHashMessageDigest5 соответственно).

Вот код для вычисления MD5:

var md5indy: TIdHashMessageDigest5; sMD5: String; begin md5indy := TIdHashMessageDigest5.Create; sMD5 := md5indy.HashStringAsHex('123456'); md5indy.Free; end;

Под Win32 результат будет: 'e10adc3949ba59abbe56e057f20f883e' (правильно)
Под Win64 результат будет: '6e692400e5c684b74314252e341b92c7' (ошибка)

Этот баг был исправлен в более поздних версиях версиях Indy/Delphi (не скажу точно, в какой именно, в Delphi 10.2 Tokyo его нет).

Баг в asm-функциях ROL и ROR в модуле IdGlobalProtocols. Вот как они выглядят в XE2:

// Arg1=EAX, Arg2=DL function ROL(const AVal: LongWord; AShift: Byte): LongWord; assembler; asm mov cl, dl rol eax, cl end; function ROR(const AVal: LongWord; AShift: Byte): LongWord; assembler; asm mov cl, dl ror eax, cl end; {$ENDIF}

А вот так это выглядит в Delpgi 10.2 Tokyo:

// 32-bit: Arg1=EAX, Arg2=DL // 64-bit: Arg1=ECX, Arg2=DL function ROL(const AVal: UInt32; AShift: Byte): UInt32; assembler; asm {$IFDEF CPU64} mov eax, ecx {$ENDIF} mov cl, dl rol eax, cl end; function ROR(const AVal: UInt32; AShift: Byte): UInt32; assembler; asm {$IFDEF CPU64} mov eax, ecx {$ENDIF} mov cl, dl ror eax, cl end;

Чтобы можно было генерировать MD4/MD5 в XE2 под Win64 без установки новой версии Indy, я сделал модуль IdHashMessageDigestEx с "исправленными" классами TIdHashMessageDigest4Ex и TIdHashMessageDigest5Ex, которыми следует пользоваться вместо TIdHashMessageDigest4 и TIdHashMessageDigest5 соответственно. Замечу, что в XE2 не работает макрос CPU64 (как в более поздних версиях Delphi), а работает CPUX64.

unit IdHashMessageDigestEx; interface uses IdFIPS, IdHashMessageDigest; type {$IFDEF VER230} //XE2 TIdHashMessageDigest4Ex = class(TIdHashMessageDigest4) protected procedure MDCoder; override; end; TIdHashMessageDigest5Ex = class(TIdHashMessageDigest4Ex) protected procedure MDCoder; override; function InitHash : TIdHashIntCtx; override; public class function IsIntfAvailable : Boolean; override; end; {$ELSE} TIdHashMessageDigest4Ex = TIdHashMessageDigest4; TIdHashMessageDigest5Ex = TIdHashMessageDigest5; {$ENDIF} implementation {$IFDEF VER230} //XE2 {$IFDEF NO_NATIVE_ASM)} //XE2 uses IdGlobalProtocols; {$ELSE} // 32-bit: Arg1=EAX, Arg2=DL // 64-bit: Arg1=ECX, Arg2=DL function ROL(const AVal: LongWord; AShift: LongWord): LongWord; assembler; asm {$IFDEF CPUX64} mov eax, ecx {$ENDIF} mov cl, dl rol eax, cl end; {$ENDIF} { TIdHashMessageDigest4Ex } {$Q-} // Arithmetic operations performed modulo $100000000 procedure TIdHashMessageDigest4Ex.MDCoder; var A, B, C, D, i : LongWord; buff : T16x4LongWordRecord; // 64-byte buffer begin A := FState[0]; B := FState[1]; C := FState[2]; D := FState[3]; for i := 0 to 15 do begin buff[i] := FCBuffer[i*4+0] + (FCBuffer[i*4+1] shl 8) + (FCBuffer[i*4+2] shl 16) + (FCBuffer[i*4+3] shl 24); end; // Round 1 { Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm } for i := 0 to 3 do begin A := ROL((((D xor C) and B) xor D) + A + buff[i*4+0], 3); D := ROL((((C xor B) and A) xor C) + D + buff[i*4+1], 7); C := ROL((((B xor A) and D) xor B) + C + buff[i*4+2], 11); B := ROL((((A xor D) and C) xor A) + B + buff[i*4+3], 19); end; // Round 2 { Note: (x and y) or (x and z) or (y and z) is equivalent to ((x and y) or (z and (x or y))) -HHellstrцm } for i := 0 to 3 do begin A := ROL(((B and C) or (D and (B or C))) + A + buff[0*4+i] + $5A827999, 3); D := ROL(((A and B) or (C and (A or B))) + D + buff[1*4+i] + $5A827999, 5); C := ROL(((D and A) or (B and (D or A))) + C + buff[2*4+i] + $5A827999, 9); B := ROL(((C and D) or (A and (C or D))) + B + buff[3*4+i] + $5A827999, 13); end; // Round 3 A := ROL((B xor C xor D) + A + buff[ 0] + $6ED9EBA1, 3); D := ROL((A xor B xor C) + D + buff[ 8] + $6ED9EBA1, 9); C := ROL((D xor A xor B) + C + buff[ 4] + $6ED9EBA1, 11); B := ROL((C xor D xor A) + B + buff[12] + $6ED9EBA1, 15); A := ROL((B xor C xor D) + A + buff[ 2] + $6ED9EBA1, 3); D := ROL((A xor B xor C) + D + buff[10] + $6ED9EBA1, 9); C := ROL((D xor A xor B) + C + buff[ 6] + $6ED9EBA1, 11); B := ROL((C xor D xor A) + B + buff[14] + $6ED9EBA1, 15); A := ROL((B xor C xor D) + A + buff[ 1] + $6ED9EBA1, 3); D := ROL((A xor B xor C) + D + buff[ 9] + $6ED9EBA1, 9); C := ROL((D xor A xor B) + C + buff[ 5] + $6ED9EBA1, 11); B := ROL((C xor D xor A) + B + buff[13] + $6ED9EBA1, 15); A := ROL((B xor C xor D) + A + buff[ 3] + $6ED9EBA1, 3); D := ROL((A xor B xor C) + D + buff[11] + $6ED9EBA1, 9); C := ROL((D xor A xor B) + C + buff[ 7] + $6ED9EBA1, 11); B := ROL((C xor D xor A) + B + buff[15] + $6ED9EBA1, 15); Inc(FState[0], A); Inc(FState[1], B); Inc(FState[2], C); Inc(FState[3], D); end; {$Q+} { TIdHashMessageDigest5Ex } const MD5_SINE : array[1..64] of LongWord = ( { Round 1. } $d76aa478, $e8c7b756, $242070db, $c1bdceee, $f57c0faf, $4787c62a, $a8304613, $fd469501, $698098d8, $8b44f7af, $ffff5bb1, $895cd7be, $6b901122, $fd987193, $a679438e, $49b40821, { Round 2. } $f61e2562, $c040b340, $265e5a51, $e9b6c7aa, $d62f105d, $02441453, $d8a1e681, $e7d3fbc8, $21e1cde6, $c33707d6, $f4d50d87, $455a14ed, $a9e3e905, $fcefa3f8, $676f02d9, $8d2a4c8a, { Round 3. } $fffa3942, $8771f681, $6d9d6122, $fde5380c, $a4beea44, $4bdecfa9, $f6bb4b60, $bebfbc70, $289b7ec6, $eaa127fa, $d4ef3085, $04881d05, $d9d4d039, $e6db99e5, $1fa27cf8, $c4ac5665, { Round 4. } $f4292244, $432aff97, $ab9423a7, $fc93a039, $655b59c3, $8f0ccc92, $ffeff47d, $85845dd1, $6fa87e4f, $fe2ce6e0, $a3014314, $4e0811a1, $f7537e82, $bd3af235, $2ad7d2bb, $eb86d391 ); {$Q-} // Arithmetic operations performed modulo $100000000 function TIdHashMessageDigest5Ex.InitHash: TIdHashIntCtx; begin Result := GetMD5HashInst; end; class function TIdHashMessageDigest5Ex.IsIntfAvailable: Boolean; begin Result := IsHashingIntfAvail and IsMD5HashIntfAvail ; end; procedure TIdHashMessageDigest5Ex.MDCoder; var A, B, C, D : LongWord; i: Integer; x : T16x4LongWordRecord; // 64-byte buffer begin A := FState[0]; B := FState[1]; C := FState[2]; D := FState[3]; for i := 0 to 15 do begin x[i] := FCBuffer[i*4+0] + (FCBuffer[i*4+1] shl 8) + (FCBuffer[i*4+2] shl 16) + (FCBuffer[i*4+3] shl 24); end; { Round 1 } { Note: (x and y) or ( (not x) and z) is equivalent to (((z xor y) and x) xor z) -HHellstrцm } A := ROL(A + (((D xor C) and B) xor D) + x[ 0] + MD5_SINE[ 1], 7) + B; D := ROL(D + (((C xor B) and A) xor C) + x[ 1] + MD5_SINE[ 2], 12) + A; C := ROL(C + (((B xor A) and D) xor B) + x[ 2] + MD5_SINE[ 3], 17) + D; B := ROL(B + (((A xor D) and C) xor A) + x[ 3] + MD5_SINE[ 4], 22) + C; A := ROL(A + (((D xor C) and B) xor D) + x[ 4] + MD5_SINE[ 5], 7) + B; D := ROL(D + (((C xor B) and A) xor C) + x[ 5] + MD5_SINE[ 6], 12) + A; C := ROL(C + (((B xor A) and D) xor B) + x[ 6] + MD5_SINE[ 7], 17) + D; B := ROL(B + (((A xor D) and C) xor A) + x[ 7] + MD5_SINE[ 8], 22) + C; A := ROL(A + (((D xor C) and B) xor D) + x[ 8] + MD5_SINE[ 9], 7) + B; D := ROL(D + (((C xor B) and A) xor C) + x[ 9] + MD5_SINE[10], 12) + A; C := ROL(C + (((B xor A) and D) xor B) + x[10] + MD5_SINE[11], 17) + D; B := ROL(B + (((A xor D) and C) xor A) + x[11] + MD5_SINE[12], 22) + C; A := ROL(A + (((D xor C) and B) xor D) + x[12] + MD5_SINE[13], 7) + B; D := ROL(D + (((C xor B) and A) xor C) + x[13] + MD5_SINE[14], 12) + A; C := ROL(C + (((B xor A) and D) xor B) + x[14] + MD5_SINE[15], 17) + D; B := ROL(B + (((A xor D) and C) xor A) + x[15] + MD5_SINE[16], 22) + C; { Round 2 } { Note: (x and z) or (y and (not z) ) is equivalent to (((y xor x) and z) xor y) -HHellstrцm } A := ROL(A + (C xor (D and (B xor C))) + x[ 1] + MD5_SINE[17], 5) + B; D := ROL(D + (B xor (C and (A xor B))) + x[ 6] + MD5_SINE[18], 9) + A; C := ROL(C + (A xor (B and (D xor A))) + x[11] + MD5_SINE[19], 14) + D; B := ROL(B + (D xor (A and (C xor D))) + x[ 0] + MD5_SINE[20], 20) + C; A := ROL(A + (C xor (D and (B xor C))) + x[ 5] + MD5_SINE[21], 5) + B; D := ROL(D + (B xor (C and (A xor B))) + x[10] + MD5_SINE[22], 9) + A; C := ROL(C + (A xor (B and (D xor A))) + x[15] + MD5_SINE[23], 14) + D; B := ROL(B + (D xor (A and (C xor D))) + x[ 4] + MD5_SINE[24], 20) + C; A := ROL(A + (C xor (D and (B xor C))) + x[ 9] + MD5_SINE[25], 5) + B; D := ROL(D + (B xor (C and (A xor B))) + x[14] + MD5_SINE[26], 9) + A; C := ROL(C + (A xor (B and (D xor A))) + x[ 3] + MD5_SINE[27], 14) + D; B := ROL(B + (D xor (A and (C xor D))) + x[ 8] + MD5_SINE[28], 20) + C; A := ROL(A + (C xor (D and (B xor C))) + x[13] + MD5_SINE[29], 5) + B; D := ROL(D + (B xor (C and (A xor B))) + x[ 2] + MD5_SINE[30], 9) + A; C := ROL(C + (A xor (B and (D xor A))) + x[ 7] + MD5_SINE[31], 14) + D; B := ROL(B + (D xor (A and (C xor D))) + x[12] + MD5_SINE[32], 20) + C; { Round 3. } A := ROL(A + (B xor C xor D) + x[ 5] + MD5_SINE[33], 4) + B; D := ROL(D + (A xor B xor C) + x[ 8] + MD5_SINE[34], 11) + A; C := ROL(C + (D xor A xor B) + x[11] + MD5_SINE[35], 16) + D; B := ROL(B + (C xor D xor A) + x[14] + MD5_SINE[36], 23) + C; A := ROL(A + (B xor C xor D) + x[ 1] + MD5_SINE[37], 4) + B; D := ROL(D + (A xor B xor C) + x[ 4] + MD5_SINE[38], 11) + A; C := ROL(C + (D xor A xor B) + x[ 7] + MD5_SINE[39], 16) + D; B := ROL(B + (C xor D xor A) + x[10] + MD5_SINE[40], 23) + C; A := ROL(A + (B xor C xor D) + x[13] + MD5_SINE[41], 4) + B; D := ROL(D + (A xor B xor C) + x[ 0] + MD5_SINE[42], 11) + A; C := ROL(C + (D xor A xor B) + x[ 3] + MD5_SINE[43], 16) + D; B := ROL(B + (C xor D xor A) + x[ 6] + MD5_SINE[44], 23) + C; A := ROL(A + (B xor C xor D) + x[ 9] + MD5_SINE[45], 4) + B; D := ROL(D + (A xor B xor C) + x[12] + MD5_SINE[46], 11) + A; C := ROL(C + (D xor A xor B) + x[15] + MD5_SINE[47], 16) + D; B := ROL(B + (C xor D xor A) + x[ 2] + MD5_SINE[48], 23) + C; { Round 4. } A := ROL(A + ((B or not D) xor C) + x[ 0] + MD5_SINE[49], 6) + B; D := ROL(D + ((A or not C) xor B) + x[ 7] + MD5_SINE[50], 10) + A; C := ROL(C + ((D or not B) xor A) + x[14] + MD5_SINE[51], 15) + D; B := ROL(B + ((C or not A) xor D) + x[ 5] + MD5_SINE[52], 21) + C; A := ROL(A + ((B or not D) xor C) + x[12] + MD5_SINE[53], 6) + B; D := ROL(D + ((A or not C) xor B) + x[ 3] + MD5_SINE[54], 10) + A; C := ROL(C + ((D or not B) xor A) + x[10] + MD5_SINE[55], 15) + D; B := ROL(B + ((C or not A) xor D) + x[ 1] + MD5_SINE[56], 21) + C; A := ROL(A + ((B or not D) xor C) + x[ 8] + MD5_SINE[57], 6) + B; D := ROL(D + ((A or not C) xor B) + x[15] + MD5_SINE[58], 10) + A; C := ROL(C + ((D or not B) xor A) + x[ 6] + MD5_SINE[59], 15) + D; B := ROL(B + ((C or not A) xor D) + x[13] + MD5_SINE[60], 21) + C; A := ROL(A + ((B or not D) xor C) + x[ 4] + MD5_SINE[61], 6) + B; D := ROL(D + ((A or not C) xor B) + x[11] + MD5_SINE[62], 10) + A; C := ROL(C + ((D or not B) xor A) + x[ 2] + MD5_SINE[63], 15) + D; B := ROL(B + ((C or not A) xor D) + x[ 9] + MD5_SINE[64], 21) + C; Inc(FState[0], A); Inc(FState[1], B); Inc(FState[2], C); Inc(FState[3], D); end; {$Q+} {$ENDIF} end.

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru