How to check function is payable or not? - ethereum

How to check in code (on Solidity side or/and Web3 side) before call contract function, this function is payable or not?
For example I found this today in token EURS
function transfer (address _to, uint256 _value)
public payable returns (bool success);
This is not standard make erc20 transfer function as payable!!! And this is not standard logic make bugs in my app, if user use EURS token.
This is standard
function transfer(address to, uint tokens) public returns (bool
success);
So I need, or override this is no standard transfer on my app contract side, or in worst case do ban such tokens on frontend side.

In one line: there is no way to check externally or from within solidity if a function is payable or not without knowing the abi / interface.
What is payable?
Payable works like any other modifier in Solidity. It runs just before executing the function it is applied on.
Payable is required to receive ether. If you send ether in a transaction to a non-payable function the transaction is reverted.

To answer your question in one line-:
Any function which is marked as payable can be considered to receive ethers.
function testPayable() external payable {...}
The above function is payable and hence can receive.
But make no mistake payable keyword is only used to receive Ethers and not ERC20 tokens.
So in your case as far as I can see the transfer function is marked as payable, which should not be the case if it is ERC20 token.
Something sounds fishy to me, isn't it to you?

Related

GMail API set non-primary send as signature return error 403

I'm making an application that should set the signature for every user in the domain. When I try to set the signature on primary aliases this work fine, but this solution is not working for other aliases (non-primary aliases).
I use a domain wide delegation that is working fine since I can set the signature for all primary send as aliases in the domain. To do so I use the request : 'www.googleapis.com/gmail/v1/users/<email_address>/settings/sendAs/<alias_address>'. When I do the exact same thing for non-primary aliases I receive an error 403 with a message telling i'm missing the scope 'www.googleapis.com/auth/gmail.settings.sharing'.
Missing required scope "https://www.googleapis.com/auth/gmail.settings.sharing" for modifying non-primary SendAs
These are the scopes I use in my code :
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.settings.basic",
"https://www.googleapis.com/auth/gmail.settings.sharing",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/admin.directory.user.readonly",
"https://www.googleapis.com/auth/drive.readonly"
]
As you can see the scope 'sharing' is present.
// The service that allow me to list send as alias
var serviceListe = getDomainWideDelegationService('Gmail: ', 'https://www.googleapis.com/auth/gmail.settings.basic', user.primaryEmail)
// THe service that allow me to edit send as signature
var serviceModif = getDomainWideDelegationService('Gmail: ', 'https://www.googleapis.com/auth/gmail.settings.sharing', user.primaryEmail)
The code that returns the domain-wide delegation :
function getDomainWideDelegationService(serviceName, scope, email) {
return OAuth2.createService(serviceName + email)
// Set the endpoint URL.
.setTokenUrl('https://oauth2.googleapis.com/token')
// Set the private key and issuer.
.setPrivateKey(OAUTH2_SERVICE_ACCOUNT_PRIVATE_KEY)
.setIssuer(OAUTH2_SERVICE_ACCOUNT_CLIENT_EMAIL)
// Set the name of the user to impersonate. This will only work for
// Google Apps for Work/EDU accounts whose admin has setup domain-wide
// delegation:
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
.setSubject(email)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scope. This must match one of the scopes configured during the
// setup of domain-wide delegation.
.setScope(scope);
}
According to the documentation here:
scope - this field specifies a space-delimited list of access scopes that correspond to the resources that your application could access on the user's behalf. These values inform the consent screen that Google displays to the user.
Taking this into account, I suggest you separate the scopes using spaces and not commas.
Reference
OAuth 2.0 for Client-side Web Applications.

Deleted Lambda Function Still Executing

We have a aws lambda function that processes some data and incase there is an error it sends out an email.
We experienced a surge of email from the lambda function so we changed the script and disabled the part where it sends email. Unfortunately we still see the emails comming in.
So we deleted the function and we still keep receiving the error emails.
How can the lambda function still be running. Would i be experiencing charges since the function is running.
John

Solidity payable function payout

Maybe I didn't understand the concept of the payable function...
So I have function like this:
function fundEthereum () payable {
}
Now as I understood this, Ethers are sent to this function and stored inside of the contract.
What I now want to do is, when someone sends ether to this function, send these ether furter to another account / address.
The question is how can I send these ethers further to another address?
Thanks for the help
Wish you a merry christmas
You have correctly understood.
I think what you want to send is the total ammount of ether sended in the function, you can found them in the msg.value . You need the receiver address, then you can send him the amount transaction with the send function.
function send(address _receiverAddress) payable {
_receiverAddress.send(msg.value);
};

UrlFetchApp.fetch returns bad request but service call works in the browser

I'm creating a google add-on that uses a restservice (GET). When I call the service from the address bar of the browser it works.
When I execute the code below I get "Bad request" as response.
function execute() {
var service= restservice;
var response = UrlFetchApp.fetch(service);
Logger.log(response);
return;
}
The scope script.external_request has been added to the manifest.
Can somebody tell me what I'm doing wrong?
From Gmail Add-ons documentation:
If the add-on script uses UrlFetch to retrieve data, you must
whitelist the URLs it accesses using the urlFetchWhitelist field in
the add-on manifest.
Perhaps this will work with non-Gmail add-ons as well?
More details https://developers.google.com/gmail/add-ons/how-tos/publish
We have found the problem.
The rest service was translated to an internal IP address.

Serving JSON from Google Apps Script as "user accessing the web-app"

Trying to serve a JSON request made by a Google Apps Script as the user who is making the request. After thinking for a while, I realized that this cannot work, because the serving script needs to be authorized to run as the user who calls him, so the calling script would have to add some authorization info, which it doesn't, and I have no idea how to add that information (that is actually my question: which information to add to the http-request, and from where to get it).
But, nevertheless, when I call that server from within the browser, it works because the browser (in which I am logged into my Google account) sends the right info in the http-request to prove that it is authorized.
This question is somehow related to the question How to use Google Apps Script ContentService as a REST server, but the answer given there is exactly what I don't want: The invoked JSON-Server should not run under my account, but under the account of the invoking user and use that users resources (scriptdb, drive, ...).
So the question is: How to provide that information from one script run from a Google-account to another script, so that this other script can run within that account? I know that using gas-libraries solves that issue, but I would like to have it as JSON-client/server (Mainly to decouple dependencies). To add some code (to keep the Stack Overflow-spirit running), my client:
var scriptUrl="https://script.google.com/macros/s/paperlapapp1231231/exec";
function callIt (nm, args) {
var a=[nm];
for (x in args) {
a.push(args[x]);
}
return Utilities.jsonParse(UrlFetchApp.fetch(scriptUrl+"?args="
+encodeURIComponent(Utilities.jsonStringify(a))).getContentText());
}
function testFunction (p1, p2, p3) { // this is the proxy
return callIt ("testFunction", arguments);
}
// Testroutine
function callTest() {
var r=testFunction (9, "XXXlala", {"dudu":1, "dada":"xxx"});
Logger.log ("r="+Utilities.jsonStringify(r));
}
My server:
function doGet(request) {
var ret=null;
try {
Logger.log ("I got called with "+JSON.stringify(request));
var args=JSON.parse(decodeURIComponent (request.parameters.args));
ret=ContentService.createTextOutput(
JSON.stringify(this[args.shift()].apply (this, args)))
.setMimeType(ContentService.MimeType.JSON);
}
catch (e) {
ret=ContentService.createTextOutput(JSON.stringify(e))
.setMimeType(ContentService.MimeType.JSON);
}
return ret;
}
function testFunction (p1, p2, p3) { // this is the implementation
var s="testing called p1="+p1+", p2="+p2+", p3="+p3;
Logger.log (s);
return {testingResult:s};
}
EDIT:
Worked out a solution, but requires a Chrome extension and an intermediate proxy server. See code at https://bitbucket.org/pbhd/gas-rest-server-as-calling-user
Edit: This was not possible before, as my answer below reflects.
However, Google does allow this now, see Execution API
https://developers.google.com/apps-script/execution/rest/v1/scripts/run
Its not possible to do that from Google Apps Script. If I understand it correctly you are calling another Google Apps Script with urlFetch.
Since Google Apps Script doesn't have an oAuth scope you can't make an authenticated call. You can only call a webapp service published as anonymous thus will run always under owner permissions.
You can't do it with libraries either unless the initial script is also called with user permissions and not owner.