From d0bb87ae88602f4afc091d9cda1be352258a6df9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 10 Mar 2016 15:56:25 +0100 Subject: Documentation for delegatecall. --- docs/contracts.rst | 43 ++++++++----------------------------------- 1 file changed, 8 insertions(+), 35 deletions(-) (limited to 'docs/contracts.rst') diff --git a/docs/contracts.rst b/docs/contracts.rst index b2358af5..2ab03849 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -679,7 +679,7 @@ Such contracts cannot be compiled (even if they contain implemented functions al If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it will itself be abstract. -.. index:: ! library, callcode +.. index:: ! library, callcode, delegatecall .. _libraries: @@ -688,7 +688,8 @@ Libraries ************ Libraries are similar to contracts, but their purpose is that they are deployed -only once at a specific address and their code is reused using the `CALLCODE` +only once at a specific address and their code is reused using the `DELEGATECALL` +(`CALLCODE` until homestead) feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e. `this` points to the calling contract and especially the storage from the calling contract can be @@ -755,12 +756,12 @@ reference parameters, can have multiple storage reference parameters and in any position. The calls to `Set.contains`, `Set.insert` and `Set.remove` -are all compiled as calls (`CALLCODE`s) to an external +are all compiled as calls (`DELEGATECALL`s) to an external contract/library. If you use libraries, take care that an -actual external function call is performed, so `msg.sender` -does not point to the original sender anymore but to the the -calling contract and also `msg.value` contains the funds -sent during the call to the library function. +actual external function call is performed. +`msg.sender`, `msg.value` and `this` will retain their values +in this call, though (prior to Homestead, `msg.sender` and +`msg.value` changed, though). As the compiler cannot know where the library will be deployed at, these addresses have to be filled into the @@ -780,34 +781,6 @@ Restrictions for libraries in comparison to contracts: (these might be lifted at a later point) -Common pitfalls for libraries -============================= - -.. index:: msg;sender - -The value of `msg.sender` -------------------------- - -The value for `msg.sender` will be that of the contract which is calling the library function. - -For example, if A calls contract B which internally calls library C, then within the function call of library C, `msg.sender` will be the address of contract B. - -The reason for this is that the expression `LibraryName.functionName()` -performs an external function call using `CALLCODE`, which maps to a real EVM -call just like `otherContract.functionName()` or `this.functionName()`. This -call extends the call depth by one (limited to 1024), stores the caller (the -current contract) as `msg.sender`, and then executes the library contract's -code against the current contracts storage. This execution occurs in a -completely new memory context meaning that memory types will be copied and -cannot be passed by reference. - -Transferring Ether -------------------------- - -It is *in principle* possible to transfer ether using -`LibraryName.functionName.value(x)()`, but as `CALLCODE` is used, the Ether -will just end up at the current contract. - .. index:: ! using for, library .. _using-for: -- cgit