Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
3aa0410f
Commit
3aa0410f
authored
Jan 23, 2015
by
Paweł Bylica
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/develop' into pr/evmjit
parents
d5f38f56
d792e95c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
184 additions
and
119 deletions
+184
-119
README.md
README.md
+1
-1
browser.qml
cmd/mist/assets/qml/browser.qml
+7
-25
main.qml
cmd/mist/assets/qml/main.qml
+30
-33
whisper.qml
cmd/mist/assets/qml/views/whisper.qml
+0
-1
ui_lib.go
cmd/mist/ui_lib.go
+2
-7
crypto.go
crypto/crypto.go
+111
-1
crypto_test.go
crypto/crypto_test.go
+13
-1
key.go
crypto/key.go
+5
-4
key_store_passphrase.go
crypto/key_store_passphrase.go
+1
-45
key_store_test.go
crypto/key_store_test.go
+13
-0
peer.go
whisper/peer.go
+1
-1
No files found.
README.md
View file @
3aa0410f
...
...
@@ -46,7 +46,7 @@ Go Ethereum comes with several binaries found in
*
`mist`
Official Ethereum Browser
*
`ethereum`
Ethereum CLI
*
`ethtest`
test tool which runs with the
[
tests
](
https://github.com/ethereum/testes
)
suit:
`
ethtest "`
cat myfile.json
`"
`
.
`
cat file | ethtest
`
.
*
`evm`
is a generic Ethereum Virtual Machine:
`evm -code 60ff60ff -gas
10000 -price 0 -dump`
. See
`-h`
for a detailed description.
...
...
cmd/mist/assets/qml/browser.qml
View file @
3aa0410f
...
...
@@ -9,15 +9,16 @@ import Ethereum 1.0
Rectangle
{
id
:
window
objectName
:
"browserView"
anchors.fill
:
parent
color
:
"#00000000"
property
var
title
:
"
Browser
"
property
var
title
:
"
DApps
"
property
var
iconSource
:
"../browser.png"
property
var
menuItem
property
var
hideUrl
:
true
property
alias
url
:
webview
.
url
property
alias
windowTitle
:
webview
.
title
property
alias
webView
:
webview
property
var
cleanPath
:
false
...
...
@@ -66,8 +67,7 @@ Rectangle {
webview
.
url
=
"http://etherian.io"
}
signal
messages
(
var
messages
,
int
id
);
onMessages
:
{
function
messages
(
messages
,
id
)
{
// Bit of a cheat to get proper JSON
var
m
=
JSON
.
parse
(
JSON
.
parse
(
JSON
.
stringify
(
messages
)))
webview
.
postEvent
(
"eth_changed"
,
id
,
m
);
...
...
@@ -164,22 +164,10 @@ Rectangle {
id
:
webview
anchors.fill
:
parent
function
injectJs
(
js
)
{
webview
.
experimental
.
navigatorQtObjectEnabled
=
true
;
webview
.
experimental
.
evaluateJavaScript
(
js
)
webview
.
experimental
.
javascriptEnabled
=
true
;
}
function
sendMessage
(
data
)
{
webview
.
experimental
.
postMessage
(
JSON
.
stringify
(
data
))
}
Component.onCompleted
:
{
for
(
var
i
in
experimental
.
preferences
)
{
console
.
log
(
i
)
}
}
experimental.preferences.javascriptEnabled
:
true
experimental.preferences.webAudioEnabled
:
true
experimental.preferences.pluginsEnabled
:
true
...
...
@@ -219,8 +207,7 @@ Rectangle {
}
experimental.userScripts
:
[
"../ext/q.js"
,
"../ext/ethereum.js/lib/web3.js"
,
"../ext/ethereum.js/lib/qt.js"
,
"../ext/setup.js"
]
experimental.onMessageReceived
:
{
console
.
log
(
"[onMessageReceived]: "
,
message
.
data
)
// TODO move to messaging.js
//console.log("[onMessageReceived]: ", message.data)
var
data
=
JSON
.
parse
(
message
.
data
)
try
{
...
...
@@ -350,13 +337,13 @@ Rectangle {
case
"eth_newFilterString"
:
require
(
1
)
var
id
=
eth
.
newFilterString
(
data
.
args
[
0
])
var
id
=
eth
.
newFilterString
(
data
.
args
[
0
]
,
window
)
postData
(
data
.
_id
,
id
);
break
;
case
"eth_newFilter"
:
require
(
1
)
var
id
=
eth
.
newFilter
(
data
.
args
[
0
])
var
id
=
eth
.
newFilter
(
data
.
args
[
0
]
,
window
)
postData
(
data
.
_id
,
id
);
break
;
...
...
@@ -425,11 +412,9 @@ Rectangle {
}
}
function
post
(
seed
,
data
)
{
postData
(
data
.
_id
,
data
)
}
function
require
(
args
,
num
)
{
if
(
args
.
length
<
num
)
{
throw
(
"required argument count of "
+
num
+
" got "
+
args
.
length
);
...
...
@@ -441,12 +426,10 @@ Rectangle {
function
postEvent
(
event
,
id
,
data
)
{
webview
.
experimental
.
postMessage
(
JSON
.
stringify
({
data
:
data
,
_id
:
id
,
_event
:
event
}))
}
function
onWatchedCb
(
data
,
id
)
{
var
messages
=
JSON
.
parse
(
data
)
postEvent
(
"watched:"
+
id
,
messages
)
}
function
onNewBlockCb
(
block
)
{
postEvent
(
"block:new"
,
block
)
}
...
...
@@ -460,7 +443,6 @@ Rectangle {
}
}
Rectangle
{
id
:
sizeGrip
color
:
"gray"
...
...
cmd/mist/assets/qml/main.qml
View file @
3aa0410f
...
...
@@ -13,7 +13,6 @@ ApplicationWindow {
id
:
root
property
var
ethx
:
Eth
.
ethx
property
var
browser
width
:
1200
height
:
820
...
...
@@ -21,6 +20,7 @@ ApplicationWindow {
title
:
"Mist"
/*
// This signal is used by the filter API. The filter API connects using this signal handler from
// the different QML files and plugins.
signal messages(var messages, int id);
...
...
@@ -30,6 +30,7 @@ ApplicationWindow {
messages(data, receiverSeed);
root.browser.view.messages(data, receiverSeed);
}
*/
TextField
{
id
:
copyElementHax
...
...
@@ -45,8 +46,6 @@ ApplicationWindow {
// Takes care of loading all default plugins
Component.onCompleted
:
{
var
wallet
=
addPlugin
(
"./views/wallet.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"ethereum"
,
active
:
true
});
var
browser
=
addPlugin
(
"./browser.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"ethereum"
,
active
:
true
});
root
.
browser
=
browser
;
addPlugin
(
"./views/miner.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"ethereum"
,
active
:
true
});
addPlugin
(
"./views/transaction.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"legacy"
});
...
...
@@ -55,17 +54,17 @@ ApplicationWindow {
addPlugin
(
"./views/pending_tx.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"legacy"
});
addPlugin
(
"./views/info.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"legacy"
});
addPlugin
(
"./views/jeffcoin/jeffcoin.qml"
,
{
noAdd
:
true
,
close
:
false
,
section
:
"apps"
})
mainSplit
.
setView
(
wallet
.
view
,
wallet
.
menuItem
);
newBrowserTab
(
"http://etherian.io"
);
// Command setup
gui
.
sendCommand
(
0
)
}
function
activeView
(
view
,
menuItem
)
{
mainSplit
.
setView
(
view
,
menuItem
)
if
(
view
.
objectName
===
"browserView"
)
{
if
(
view
.
hideUrl
)
{
urlPane
.
visible
=
false
;
mainView
.
anchors
.
top
=
rootView
.
top
}
else
{
...
...
@@ -119,6 +118,13 @@ ApplicationWindow {
}
}
function
newBrowserTab
(
url
)
{
var
window
=
addPlugin
(
"./browser.qml"
,
{
noAdd
:
true
,
close
:
true
,
section
:
"apps"
,
active
:
true
});
window
.
view
.
url
=
url
;
window
.
menuItem
.
title
=
"Browser Tab"
;
activeView
(
window
.
view
,
window
.
menuItem
);
}
menuBar
:
MenuBar
{
Menu
{
title
:
"File"
...
...
@@ -130,13 +136,6 @@ ApplicationWindow {
}
}
/*
MenuItem {
text: "Browser"
onTriggered: eth.openBrowser()
}
*/
MenuItem
{
text
:
"Add plugin"
onTriggered
:
{
...
...
@@ -146,6 +145,14 @@ ApplicationWindow {
}
}
MenuItem
{
text
:
"New tab"
shortcut
:
"Ctrl+t"
onTriggered
:
{
newBrowserTab
(
"http://etherian.io"
);
}
}
MenuSeparator
{}
MenuItem
{
...
...
@@ -205,21 +212,6 @@ ApplicationWindow {
}
MenuSeparator
{}
/*
MenuItem {
id: miningSpeed
text: "Mining: Turbo"
onTriggered: {
gui.toggleTurboMining()
if(text == "Mining: Turbo") {
text = "Mining: Normal";
} else {
text = "Mining: Turbo";
}
}
}
*/
}
Menu
{
...
...
@@ -350,9 +342,6 @@ ApplicationWindow {
views
[
i
].
menuItem
.
setSelection
(
false
)
}
view
.
visible
=
true
//menu.border.color = "#CCCCCC"
//menu.color = "#FFFFFFFF"
menu
.
setSelection
(
true
)
}
...
...
@@ -512,7 +501,15 @@ ApplicationWindow {
this
.
view
.
destroy
()
this
.
destroy
()
for
(
var
i
=
0
;
i
<
mainSplit
.
views
.
length
;
i
++
)
{
var
view
=
mainSplit
.
views
[
i
];
if
(
view
.
menuItem
===
this
)
{
mainSplit
.
views
.
splice
(
i
,
1
);
break
;
}
}
gui
.
removePlugin
(
this
.
path
)
activeView
(
mainSplit
.
views
[
0
].
view
,
mainSplit
.
views
[
0
].
menuItem
);
}
}
}
...
...
@@ -576,7 +573,7 @@ ApplicationWindow {
Text
{
text
:
"
APPS
"
text
:
"
NET
"
font.bold
:
true
anchors
{
left
:
parent
.
left
...
...
@@ -653,7 +650,7 @@ ApplicationWindow {
Keys.onReturnPressed
:
{
if
(
/^https
?
/
.
test
(
this
.
text
))
{
activeView
(
root
.
browser
.
view
,
root
.
browser
.
menuItem
);
newBrowserTab
(
this
.
text
);
}
else
{
addPlugin
(
this
.
text
,
{
close
:
true
,
section
:
"apps"
})
}
...
...
cmd/mist/assets/qml/views/whisper.qml
View file @
3aa0410f
...
...
@@ -18,7 +18,6 @@ Rectangle {
property
var
identity
:
""
Component.onCompleted
:
{
identity
=
shh
.
newIdentity
()
console
.
log
(
"New identity:"
,
identity
)
var
t
=
shh
.
watch
({},
root
)
}
...
...
cmd/mist/ui_lib.go
View file @
3aa0410f
...
...
@@ -316,20 +316,15 @@ func (self *UiLib) NewFilter(object map[string]interface{}, view *qml.Common) (i
filter
:=
qt
.
NewFilterFromMap
(
object
,
self
.
eth
)
filter
.
MessageCallback
=
func
(
messages
state
.
Messages
)
{
view
.
Call
(
"messages"
,
xeth
.
ToJSMessages
(
messages
),
id
)
//self.win.Root().Call("invokeFilterCallback", xeth.ToJSMessages(messages), id)
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
return
id
}
func
(
self
*
UiLib
)
NewFilterString
(
typ
string
)
(
id
int
)
{
func
(
self
*
UiLib
)
NewFilterString
(
typ
string
,
view
*
qml
.
Common
)
(
id
int
)
{
filter
:=
core
.
NewFilter
(
self
.
eth
)
filter
.
BlockCallback
=
func
(
block
*
types
.
Block
)
{
if
self
.
win
!=
nil
&&
self
.
win
.
Root
()
!=
nil
{
self
.
win
.
Root
()
.
Call
(
"invokeFilterCallback"
,
"{}"
,
id
)
}
else
{
fmt
.
Println
(
"QML is lagging"
)
}
view
.
Call
(
"messages"
,
"{}"
,
id
)
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
return
id
...
...
crypto/crypto.go
View file @
3aa0410f
package
crypto
import
(
"crypto/aes"
"crypto/cipher"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"fmt"
"encoding/hex"
"encoding/json"
"errors"
"code.google.com/p/go-uuid/uuid"
"code.google.com/p/go.crypto/pbkdf2"
"code.google.com/p/go.crypto/ripemd160"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/crypto/sha3"
...
...
@@ -101,7 +110,11 @@ func SigToPub(hash, sig []byte) *ecdsa.PublicKey {
}
func
Sign
(
hash
[]
byte
,
prv
*
ecdsa
.
PrivateKey
)
(
sig
[]
byte
,
err
error
)
{
sig
,
err
=
secp256k1
.
Sign
(
hash
,
prv
.
D
.
Bytes
())
if
len
(
hash
)
!=
32
{
return
nil
,
fmt
.
Errorf
(
"hash is required to be exactly 32 bytes (%d)"
,
len
(
hash
))
}
sig
,
err
=
secp256k1
.
Sign
(
hash
,
ethutil
.
LeftPadBytes
(
prv
.
D
.
Bytes
(),
prv
.
Params
()
.
BitSize
/
8
))
return
}
...
...
@@ -113,3 +126,100 @@ func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
key
:=
ecies
.
ImportECDSA
(
prv
)
return
key
.
Decrypt
(
rand
.
Reader
,
ct
,
nil
,
nil
)
}
// creates a Key and stores that in the given KeyStore by decrypting a presale key JSON
func
ImportPreSaleKey
(
keyStore
KeyStore2
,
keyJSON
[]
byte
,
password
string
)
(
*
Key
,
error
)
{
key
,
err
:=
decryptPreSaleKey
(
keyJSON
,
password
)
if
err
!=
nil
{
return
nil
,
err
}
id
:=
uuid
.
NewRandom
()
key
.
Id
=
&
id
err
=
keyStore
.
StoreKey
(
key
,
password
)
return
key
,
err
}
func
decryptPreSaleKey
(
fileContent
[]
byte
,
password
string
)
(
key
*
Key
,
err
error
)
{
preSaleKeyStruct
:=
struct
{
EncSeed
string
EthAddr
string
Email
string
BtcAddr
string
}{}
err
=
json
.
Unmarshal
(
fileContent
,
&
preSaleKeyStruct
)
if
err
!=
nil
{
return
nil
,
err
}
encSeedBytes
,
err
:=
hex
.
DecodeString
(
preSaleKeyStruct
.
EncSeed
)
iv
:=
encSeedBytes
[
:
16
]
cipherText
:=
encSeedBytes
[
16
:
]
/*
See https://github.com/ethereum/pyethsaletool
pyethsaletool generates the encryption key from password by
2000 rounds of PBKDF2 with HMAC-SHA-256 using password as salt (:().
16 byte key length within PBKDF2 and resulting key is used as AES key
*/
passBytes
:=
[]
byte
(
password
)
derivedKey
:=
pbkdf2
.
Key
(
passBytes
,
passBytes
,
2000
,
16
,
sha256
.
New
)
plainText
,
err
:=
aesCBCDecrypt
(
derivedKey
,
cipherText
,
iv
)
ethPriv
:=
Sha3
(
plainText
)
ecKey
:=
ToECDSA
(
ethPriv
)
key
=
&
Key
{
Id
:
nil
,
PrivateKey
:
ecKey
,
}
derivedAddr
:=
ethutil
.
Bytes2Hex
(
key
.
Address
())
expectedAddr
:=
preSaleKeyStruct
.
EthAddr
if
derivedAddr
!=
expectedAddr
{
err
=
errors
.
New
(
"decrypted addr not equal to expected addr"
)
}
return
key
,
err
}
func
aesCBCDecrypt
(
key
[]
byte
,
cipherText
[]
byte
,
iv
[]
byte
)
(
plainText
[]
byte
,
err
error
)
{
aesBlock
,
err
:=
aes
.
NewCipher
(
key
)
if
err
!=
nil
{
return
plainText
,
err
}
decrypter
:=
cipher
.
NewCBCDecrypter
(
aesBlock
,
iv
)
paddedPlainText
:=
make
([]
byte
,
len
(
cipherText
))
decrypter
.
CryptBlocks
(
paddedPlainText
,
cipherText
)
plainText
=
PKCS7Unpad
(
paddedPlainText
)
if
plainText
==
nil
{
err
=
errors
.
New
(
"Decryption failed: PKCS7Unpad failed after decryption"
)
}
return
plainText
,
err
}
// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
func
PKCS7Pad
(
in
[]
byte
)
[]
byte
{
padding
:=
16
-
(
len
(
in
)
%
16
)
if
padding
==
0
{
padding
=
16
}
for
i
:=
0
;
i
<
padding
;
i
++
{
in
=
append
(
in
,
byte
(
padding
))
}
return
in
}
func
PKCS7Unpad
(
in
[]
byte
)
[]
byte
{
if
len
(
in
)
==
0
{
return
nil
}
padding
:=
in
[
len
(
in
)
-
1
]
if
int
(
padding
)
>
len
(
in
)
||
padding
>
aes
.
BlockSize
{
return
nil
}
else
if
padding
==
0
{
return
nil
}
for
i
:=
len
(
in
)
-
1
;
i
>
len
(
in
)
-
int
(
padding
)
-
1
;
i
--
{
if
in
[
i
]
!=
padding
{
return
nil
}
}
return
in
[
:
len
(
in
)
-
int
(
padding
)]
}
crypto/crypto_test.go
View file @
3aa0410f
...
...
@@ -52,7 +52,7 @@ func BenchmarkSha3(b *testing.B) {
}
func
Test0Key
(
t
*
testing
.
T
)
{
t
.
Skip
()
key
:=
ethutil
.
Hex2Bytes
(
"1111111111111111111111111111111111111111111111111111111111111111"
)
p
,
err
:=
secp256k1
.
GeneratePubKey
(
key
)
...
...
@@ -60,3 +60,15 @@ func Test0Key(t *testing.T) {
fmt
.
Printf
(
"%x
\n
"
,
p
)
fmt
.
Printf
(
"%v %x
\n
"
,
err
,
addr
)
}
func
TestInvalidSign
(
t
*
testing
.
T
)
{
_
,
err
:=
Sign
(
make
([]
byte
,
1
),
nil
)
if
err
==
nil
{
t
.
Errorf
(
"expected sign with hash 1 byte to error"
)
}
_
,
err
=
Sign
(
make
([]
byte
,
33
),
nil
)
if
err
==
nil
{
t
.
Errorf
(
"expected sign with hash 33 byte to error"
)
}
}
crypto/key.go
View file @
3aa0410f
...
...
@@ -57,7 +57,7 @@ type encryptedKeyJSON struct {
func
(
k
*
Key
)
Address
()
[]
byte
{
pubBytes
:=
FromECDSAPub
(
&
k
.
PrivateKey
.
PublicKey
)
return
Sha3
(
pubBytes
)[
12
:
]
return
Sha3
(
pubBytes
[
1
:
]
)[
12
:
]
}
func
(
k
*
Key
)
MarshalJSON
()
(
j
[]
byte
,
err
error
)
{
...
...
@@ -99,9 +99,10 @@ func NewKey(rand io.Reader) *Key {
privateKeyMarshalled
:=
elliptic
.
Marshal
(
S256
(),
x
,
y
)
privateKeyECDSA
:=
ToECDSA
(
privateKeyMarshalled
)
key
:=
new
(
Key
)
id
:=
uuid
.
NewRandom
()
key
.
Id
=
&
id
key
.
PrivateKey
=
privateKeyECDSA
key
:=
&
Key
{
Id
:
&
id
,
PrivateKey
:
privateKeyECDSA
,
}
return
key
}
crypto/key_store_passphrase.go
View file @
3aa0410f
...
...
@@ -178,22 +178,10 @@ func DecryptKey(ks keyStorePassphrase, keyId *uuid.UUID, auth string) (keyBytes
if
err
!=
nil
{
return
nil
,
err
}
AES256Block
,
err
:=
aes
.
NewCipher
(
derivedKey
)
plainText
,
err
:=
aesCBCDecrypt
(
derivedKey
,
cipherText
,
iv
)
if
err
!=
nil
{
return
nil
,
err
}
AES256CBCDecrypter
:=
cipher
.
NewCBCDecrypter
(
AES256Block
,
iv
)
paddedPlainText
:=
make
([]
byte
,
len
(
cipherText
))
AES256CBCDecrypter
.
CryptBlocks
(
paddedPlainText
,
cipherText
)
plainText
:=
PKCS7Unpad
(
paddedPlainText
)
if
plainText
==
nil
{
err
=
errors
.
New
(
"Decryption failed: PKCS7Unpad failed after decryption"
)
return
nil
,
err
}
keyBytes
=
plainText
[
:
len
(
plainText
)
-
32
]
keyBytesHash
:=
plainText
[
len
(
plainText
)
-
32
:
]
if
!
bytes
.
Equal
(
Sha3
(
keyBytes
),
keyBytesHash
)
{
...
...
@@ -211,35 +199,3 @@ func getEntropyCSPRNG(n int) []byte {
}
return
mainBuff
}
// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes
func
PKCS7Pad
(
in
[]
byte
)
[]
byte
{
padding
:=
16
-
(
len
(
in
)
%
16
)
if
padding
==
0
{
padding
=
16
}
for
i
:=
0
;
i
<
padding
;
i
++
{
in
=
append
(
in
,
byte
(
padding
))
}
return
in
}
func
PKCS7Unpad
(
in
[]
byte
)
[]
byte
{
if
len
(
in
)
==
0
{
return
nil
}
padding
:=
in
[
len
(
in
)
-
1
]
if
int
(
padding
)
>
len
(
in
)
||
padding
>
aes
.
BlockSize
{
return
nil
}
else
if
padding
==
0
{
return
nil
}
for
i
:=
len
(
in
)
-
1
;
i
>
len
(
in
)
-
int
(
padding
)
-
1
;
i
--
{
if
in
[
i
]
!=
padding
{
return
nil
}
}
return
in
[
:
len
(
in
)
-
int
(
padding
)]
}
crypto/key_store_test.go
View file @
3aa0410f
...
...
@@ -83,3 +83,16 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
t
.
Fatal
(
err
)
}
}
func
TestImportPreSaleKey
(
t
*
testing
.
T
)
{
// file content of a presale key file generated with:
// python pyethsaletool.py genwallet
// with password "foo"
fileContent
:=
"{
\"
encseed
\"
:
\"
26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba
\"
,
\"
ethaddr
\"
:
\"
d4584b5f6229b7be90727b0fc8c6b91bb427821f
\"
,
\"
email
\"
:
\"
gustav.simonsson@gmail.com
\"
,
\"
btcaddr
\"
:
\"
1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx
\"
}"
ks
:=
NewKeyStorePassphrase
(
DefaultDataDir
())
pass
:=
"foo"
_
,
err
:=
ImportPreSaleKey
(
ks
,
[]
byte
(
fileContent
),
pass
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
whisper/peer.go
View file @
3aa0410f
...
...
@@ -81,7 +81,7 @@ func (self *peer) broadcast(envelopes []*Envelope) error {
if
err
:=
self
.
ws
.
WriteMsg
(
msg
);
err
!=
nil
{
return
err
}
self
.
peer
.
Info
ln
(
"broadcasted"
,
i
,
"message(s)"
)
self
.
peer
.
DebugDetail
ln
(
"broadcasted"
,
i
,
"message(s)"
)
}
return
nil
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment