Skip to content

Commit 5f7375f

Browse files
authored
Merge pull request #266 from ethereum/linkViaHash
Support linking via hash.
2 parents 5b7cdba + 4ea94fb commit 5f7375f

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

linker.js

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
var keccak = require('keccak');
2+
3+
function keccak256 (input) {
4+
return keccak('keccak256').update(input).digest();
5+
}
6+
7+
function libraryHashPlaceholder (input) {
8+
return '$' + keccak256(input).toString('hex').slice(0, 34) + '$';
9+
}
10+
111
var linkBytecode = function (bytecode, libraries) {
212
// NOTE: for backwards compatibility support old compiler which didn't use file names
313
var librariesComplete = {};
@@ -19,11 +29,6 @@ var linkBytecode = function (bytecode, libraries) {
1929
}
2030

2131
for (libraryName in librariesComplete) {
22-
// truncate to 37 characters
23-
var internalName = libraryName.slice(0, 36);
24-
// prefix and suffix with __
25-
var libLabel = '__' + internalName + Array(37 - internalName.length).join('_') + '__';
26-
2732
var hexAddress = librariesComplete[libraryName];
2833
if (hexAddress.slice(0, 2) !== '0x' || hexAddress.length > 42) {
2934
throw new Error('Invalid address specified for ' + libraryName);
@@ -32,9 +37,19 @@ var linkBytecode = function (bytecode, libraries) {
3237
hexAddress = hexAddress.slice(2);
3338
hexAddress = Array(40 - hexAddress.length + 1).join('0') + hexAddress;
3439

35-
while (bytecode.indexOf(libLabel) >= 0) {
36-
bytecode = bytecode.replace(libLabel, hexAddress);
37-
}
40+
// Support old (library name) and new (hash of library name)
41+
// placeholders.
42+
var replace = function (name) {
43+
// truncate to 37 characters
44+
var truncatedName = name.slice(0, 36);
45+
var libLabel = '__' + truncatedName + Array(37 - truncatedName.length).join('_') + '__';
46+
while (bytecode.indexOf(libLabel) >= 0) {
47+
bytecode = bytecode.replace(libLabel, hexAddress);
48+
}
49+
};
50+
51+
replace(libraryName);
52+
replace(libraryHashPlaceholder(libraryName));
3853
}
3954

4055
return bytecode;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"homepage": "https://github.com/ethereum/solc-js#readme",
4141
"dependencies": {
4242
"fs-extra": "^0.30.0",
43+
"keccak": "^1.0.2",
4344
"memorystream": "^0.3.1",
4445
"require-from-string": "^2.0.0",
4546
"semver": "^5.5.0",

test/linker.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,11 @@ tape('Linking', function (t) {
139139
st.ok(bytecode.indexOf('_') < 0);
140140
st.end();
141141
});
142+
143+
t.test('hashed placeholder', function (st) {
144+
var bytecode = '6060604052341561000__$cb901161e812ceb78cfe30ca65050c4337$__66606060606060';
145+
bytecode = linker.linkBytecode(bytecode, { 'lib2.sol:L': '0x123456' });
146+
st.equal(bytecode, '6060604052341561000000000000000000000000000000000000012345666606060606060');
147+
st.end();
148+
});
142149
});

0 commit comments

Comments
 (0)